Repository navigation
Releases: openglacier/core
Release list
v2.0.2
openglacier Core v2.0.2 — antaa palaa
Writes that no longer fail because of another collection.
Highlights
- Fix : A write conflicts only with a commit that changed what it read or wrote, no longer with any commit at all.
- Fix : A write refused for a conflict runs again by itself, up to five attempts.
- Fix : No durable event is lost in silence: one that cannot be stored is said in the
ogdlog.
Storage and writes
In v2.0.0 and v2.0.1, a transaction was refused as soon as any other commit happened between its start and its
commit, whatever that commit touched, and nothing ran it again. The Core itself writes in the background: the event
outbox deletes each event once delivered, just after the operation that published it (app.create, file.write,
an import…). The next write of the same client could then fail with
storage transaction conflict: Glacier generation changed before commit: data.mapping.save right after
app.create, imports right after their file was written, two users writing at the same time.
- Conflicts per collection. A transaction notes the collections it reads (
get,scan,count) and those it
writes. Another commit makes it conflict only if it changed one of them, created it or emptied it since the
transaction's snapshot. A listing of all the collections counts as reading every one of them.- The collection a write reads its rows from is watched too, though its rows come through another snapshot
(StorageTransaction::watch_collection). - A collection read only by a
lookupis not watched: this is snapshot isolation, as in PostgreSQL's
REPEATABLE READ. - A transaction whose writes were moved out of memory (spilled) also needs each collection it writes to be exactly
as in its snapshot, not even compacted since. - The in-memory backend follows the same rule. Its commit now installs only the collections it wrote, instead of
its whole copy of the store.
- The collection a write reads its rows from is watched too, though its rows come through another snapshot
- Refused writes run again. A
set,delete,load,into,insertor a group of writes run together that
the storage refuses for a conflict is run again whole, on the state the other commit left, after 5, 10, 20 and
40 ms (plus a random part of as much). A refused write committed nothing and sent nothing. The fifth refusal is
returned. Other errors are not run again. - Events. Storing a durable event in the outbox benefits from the same retries. One that still fails is
reported in theogdlog (ogd events: the event … is lost), not only underOGD_DEBUG.
The conflict message now reads a collection of the transaction changed before commit.
Upgrading from 2.0.1
Nothing to do.
Full Changelog: v2.0.1...v2.0.2
Small core, long life.
v2.0.1
openglacier Core v2.0.1 — antaa palaa
Formulas in imports, a Fabric that welcomes every node, and a lighter build.
Highlights
- Import formulas are expressions of the language:
ht - pam, but alsoif,substr,concat, dates. - Every Core can join the Fabric with an identity issued by the Authority, not only the one that enrolled
the Gateway. - Mail through Microsoft 365 and other servers that do not offer
AUTH PLAIN. ogd --versionand--helpanswer instead of starting a daemon.- Fewer dependencies: the default build goes from 124 crates to 70, with no known vulnerability.
Import
- A calculated column of a mapping may be an expression of OGML
({"type": "formula", "target", "expression", "transform"}); the sums of signed terms stay accepted.- The expression is parsed once: one that does not parse stops the import (
formula of <target>: …). - Columns are read under their own name, or, when it is not a name of the language, lower case without accents
and_for the rest (Code article→code_article,2025→_2025). - A cell that reads as a number is a number (
1 234,50,(10)), but a code written with leading zeros stays
text (01,010178); a workbook date is its epoch milliseconds. - The result is converted as the target field is (month, date, datetime, text under its format). A row where the
expression fails getsnulland a warning; the import goes on. - The Python worker refuses expressions with a clear message: use the native worker (
native-import).
- The expression is parsed once: one that does not parse stops the import (
data.mapping.savereplaces the active mapping of the same format and table (state: "replaced"), and
data.analyzereturns the newest mappings first: a format mapped again is recognised with its last mapping.
Fabric
- A Core joining the Fabric with an identity issued by the Authority accepts the enrolled Gateway. It used to
look the Gateway's Device up in its own store, where only the Core that enrolled it holds it, and refused it in a
loop. A Core that does not know the Gateway now keeps it once it proves its key, and refuses another key or a
revoked Device afterwards; a Core without a store checks the key at each connection. - The node channels run on websockets of the Core's own (RFC 6455, TLS by rustls with the webpki roots as
before) instead oftungstenite. Nothing changes on the wire: same handshake, same limits (64 MiB a message,
16 MiB a frame), pings answered and closes echoed. Tested through the Gateway with a 1 GB file both ways, byte for
byte.
AUTH is negotiated from the server's EHLO reply (the one after STARTTLS): PLAIN when offered, else LOGIN
(inside TLS), else a clear mail.auth error naming what the server offers (XOAUTH2 only, or no AUTH at all).
ogd, glacierdb and ogcli
ogdandglacierdbanswer--version(-V,-v,version) with their version and code name and--help
(-h,-?,help) with their commands, and refuse any other argument (exit code 2). They used to start a
daemon in the current directory, which could write itsbootstrap/admin.ogidthere.data-workeris accepted only by builds withnative-import.- The terminal workspace of
ogcli --tuiis drawn withcrosstermalone; keys and behaviour are unchanged.
Builds
| Build | Crates in 2.0.0 | Crates in 2.0.1 |
|---|---|---|
| default | 124 | 70 |
cli-tui |
124 | 85 |
full |
164 | 156 |
Distinct crates and versions of the normal dependencies on Linux (cargo tree -e normal), the Core included.
search-documentsleaves the default build and stays infull: the defaultogdsearches values, files by
path, plain text files and Apps, but no longer reads the text of PDF and office documents. Build with
--features search-documents, or useog-core-full, to keep it.ratatuiandtungsteniteare no longer dependencies. The text of PDF files is read bylopdf0.46 itself instead
ofpdf-extract, which heldlopdfat 0.42 and its unmaintained font parserttf-parser(RUSTSEC-2026-0192).
Security
zstd 0.14.3 (zstd-safe 8.2) for RUSTSEC-2026-0391, -0398 and -0403 and the unsound advisories of
zstd-safe 7. sha1 0.11. ttf-parser (unmaintained, RUSTSEC-2026-0192) is gone with pdf-extract, and
clipboard-win 5.4.1, yanked, is now 5.4.3. cargo audit reports neither vulnerability nor warning.
Upgrading from 2.0.0
Replace the binaries; stores, backups, identities and Apps stay as they are. Two things to check:
- if you rely on the text of PDF and office documents in
place.search, runog-core-fullor a build with
search-documents; - mappings that use formula expressions need the native data worker (the default when
native-importis
compiled).
Full Changelog: v2.0.0...v2.0.1
Small core, long life.
v2.0.0
openglacier Core v2.0.0 — antaa palaa, continued
Glacier 6 goes public, Places become searchable, and the Core learns to run a whole organisation.
openglacier Core v2.0.0 carries on the antaa palaa line opened by v1.0: same code name, same promise. The
architecture stays the one you can build on; what changes is how much of it is now in your hands.
The major version moves for one reason: the storage format changes. Every public 1.0.x build stored its
data with Glacier 5. v2.0.0 publishes Glacier 6, the column-segment store the Core has been developed and
tested on, and reads format 6 only. Upgrading is one backup and one restore (see Upgrading from 1.0.x).
Highlights
- Glacier 6, a column-segment storage engine, now in the public tree.
- Backups of their own: OGB2, columnar and compressed, with diffs, chains and full history.
- Place search:
place.searchover values, files and Apps, including the text of PDF and office documents. - Native data import: CSV, text and Excel without Python, streamed batch by batch.
- OGML without
|: stages separated by line breaks or;, and expressions directly ingroupandpivot. - A scheduler instead of rejections: light and heavy pools, a waiting queue, admission by learned memory peak.
- Policies and pools: enrollment by policy token, usage accounting, enforced limits, App offers.
- Durable machine access, mail, public Places on demand.
- Base Apps read from a file, so a distribution can ship its own set.
- New release archives:
og-core-fullandog-cli-tui, with build provenance attestations.
Glacier 6
Glacier is a column-segment store, on-disk format version 6. A store is a directory:
<store>/
MANIFEST live segments, deleted rows, field facts, at one generation
0000000000000005.g6 immutable column segments, one collection each
wal-00000007.log commits after the manifest generation
LOCK held by the one process that has the store open
- Rows are sorted by identifier and split into row groups of up to 65,536 rows, with one chunk per top-level
field. Scalar leaves of object fields are stored as their own columns. - Each stream picks its smallest encoding: frame of reference and bit packing, sorted dictionaries, scaled
decimals that stay bit-exact, string dictionaries. - Per-chunk statistics (kinds present, smallest and largest value) feed the planner, which uses them to prove
expressions total and to skip row groups that leading filters drop. - Typed blocks decode straight into the query engine's batches: filters, groups, distinct, pivot and Top-N run on
typed columns and dictionary codes instead of documents.
It is also stricter about what it accepts:
- data without a manifest is refused;
- the store is locked by one process;
- corruption in the middle of the log is refused instead of being silently truncated;
- segment chunks are verified against their checksum on first read;
- a store of another format, or a manifest written by a newer
ogd, is reported as such, not as corrupt data:
... is a Glacier store of format 5 (ogd 1.x): this ogd reads format 6 only
The format is documented in src/storage/backend/GLACIER.md.
Backups: OGB2, diffs and history
Backups now have a format of their own, independent of the storage files.
- OGB2 writes each collection in blocks of 65,536 documents laid out by field (identifiers and integers as
deltas, strings through a block dictionary, exact types kept), compressed with zstd. On a 6.2 M-document store,
a backup went from 1.52 GB to 73.6 MB, and its restore from 54.8 s to 21.7 s. A store restored then backed up
again gives the same bytes. - Diffs:
backup.createwith aparentwrites only what changed since the parent. Restoring a diff
restores its whole chain, which is found and checked before the store is touched. Diffs need the history
(OGD_HISTORY=on) or the lighter backup journal (OGD_HISTORY=journal), which keeps the commits since the last
full backup. - Full backups with history:
backup.create {"history": true}writes the state, then the history of every
collection and the timeline of commit times and authors.ogd restore-backup <backup.ogb> <new-store-directory>
rebuilds that history offline, with its original generations, times and authors, soas ofandhistory
answer as they did on the source. - OGB1 backups written by
1.0.xare still read.
Place search
place.search finds what a Place holds by its words (feature search, in the default and full builds):
- the distinct text values of its collections, with their row count;
- its files and folders, by path;
- its App instances and tables.
Accents, case, plurals and acronyms are folded, prefixes match, and a typo is accepted only when no entry holds
the word as typed; scores weigh rare words higher. Scope keys narrow a search: app:, collection:, field:,
folder:. A search reads only what the caller may read (visible Apps, row filters).
With search-documents (default and full), the text of files is searched too: plain text, PDF, spreadsheets
(xlsx, xls, ods) and office documents (docx, pptx, odt, odp), cut into passages of about 1,000 characters. A file
that cannot be read is still found by its name; files over 32 MB are not read.
The index is made of parts, one per source, each read again only when its collection or file changes: after a
first search of about a second on a large Place, the next ones answer in milliseconds.
Native data import
data.import no longer needs Python.
ogd data-worker(featurenative-import, included infull) reads CSV, text and Excel files in a
process of its own and answers the same protocol as the Python worker. When it is compiled, it is the worker;
OG_DATA_WORKER=pythonasks for the Python one instead.- It reproduces the Python worker's fingerprints, separators, headers, column profiles and date rules, and goes
further: UTF-16, workbooks recognised by their content, named Excel tables, several tables per sheet, merged
cells and group headers. A doubtful date becomesnullinstead of stopping the whole import. - Imports are streamed batch by batch (5,000 rows or about 1 MB each): a file of any size goes through,
and no step holds it whole. One million rows through a Gateway: 113 s and 1.39 GiB, where it took 9.85 GiB
before. - The last step of an import, moving the staged rows into their collection, now stays within the query's memory.
OGML
Without |
A query that holds no top-level | may separate its stages with line breaks and ;, and reads as the
same stages:
on sales
where amount > 100
group
by region
sum amount as total
end
sort total desc
on sales; where amount > 100; count
| stays exactly as it was: a query holding one reads as before. A line break ends a stage when brackets are
balanced, the line does not end on a continuation, and the next line starts with a stage word or a directive of
its block. One style per query; errors give the line.
Also new
- Expressions with an alias as compact group items, group keys and pivot rows and columns:
on sales | group region, revenue - cost as marginsums the margin per region. - Functions:
median,percentile,stddev,month_end,days_in, andhalf_evenrounding. - Values of different kinds sort by kind instead of failing.
- Materialized views follow the views they read, at any depth, and are computed again when one of them is
redefined.
Running under load
- Light and heavy pools with a waiting queue: queries wait for their turn instead of being rejected. Heavy
queries are admitted by their learned memory peak rather than a fixed count; operators that cannot spill
wait for released memory, and pivot cells now spill and merge back. On a 1 GB node, every level of the
concurrent load campaign completes, with twice the throughput and no errors down to 256 MB. - Result cache of Place reads (
OGD_RESULT_CACHE, on by default): rows are kept under the prepared text,
the Place, the caller's access filters and the change tokens of everything the read touches, so they are never
stale. Identical reads arriving together wait for one execution. Five simultaneous logins on a demo stack:
32.2 s → 1.3 s. OGD_QUERY_TRACEwrites one JSON line perquery.execute.- Node channels relay as soon as they can: an exchange through a Gateway channel takes 74 µs instead of
27 ms, and 100 MiB move at 1,480 MiB/s instead of 266.
Policies and pools
A Core can now serve many organisations under explicit rules (OGD_ENROLLMENT_MODE=policy):
- a pool is a client organisation; a policy belongs to a pool and carries optional limits, per-user
limits, rights and an App selection; - identities enroll with a policy token (
ogp_…, shown once, stored as a SHA-256); - usage is computed per Place, owner, policy and pool (
usage.get, everyOGD_USAGE_INTERVALseconds); - limits are enforced: Places, storage (writes that add documents, imports and file writes are refused past
the limit, whilesetanddeletestill pass), devices, public and external sharing; - Apps: a policy offers some Apps as included and others as add-ons; an instance whose App is no longer
included turns read-only; - identities can be deactivated (
identity.state.set), which frees their seat.
New operations: pool.*, policy.*, policy.token.*, identity.policy.set, identity.state.set,
usage.get. Without OGD_ENROLLMENT_MODE=policy, nothing changes.
Access
- **Durable machine ...
v1.0.5
openglacier Core v1.0.5 — antaa palaa
Security update.
Dependencies updated after cargo audit. No change of behaviour; v1.0.4 stores and backups are used as they
are.
It is the last release before v2.0.0, which moves from Glacier 5 to Glacier 6 (upgrade through a backup).
Full Changelog: v1.0.4...v1.0.5
Small core, long life.
v1.0.4
openglacier Core v1.0.4 — antaa palaa
Time travel, views and windows: OGML grows up.
v1.0.4 gathers the work of the unpublished 1.0.3. Public 1.0.x builds keep storing their data with
Glacier 5; the column-segment store developed alongside arrives with v2.0.0.
Language
- Past states and history:
on c as of …reads a collection as it was,on c historyreads its stored
versions. - Views:
define viewandundefine view, versioned and read per Place. A view reads like a collection, as
a source, aunionbranch or alookup, with the caller's variables. Materialized views are kept per scope
until a collection they read changes. window:lag,lead,cumsum,first,lastandrow_numberover ordered partitions.filladds the rows missing from a grid (fill month from 1 to 12 step 1 by region), so series have
no holes.- Fiscal dates:
fiscal_year,fiscal_month,fiscal_startandfiscal_end, for years that close at the end
of any month. letcan hold the rows of a query, and takes defaults.unionbranches andlookupstages run any pipeline; lookups match on prefixes;groupcollects values with
list.- Sorting values of different kinds is refused with an error instead of stopping the daemon.
Engine
- Filters move towards the source past stages that leave their fields and rows alone.
- Comparisons, distinct, group, pivot and Top-N run on typed batches with a shared key table; Top-N keeps its
rows in a heap. - Writes stream into one transaction behind a streamed read, and several writes can share one transaction.
- Streaming responses are written in batches.
- Every query stage is declared once, in a catalogue.
Apps
- Apps can deliver standard views from their definitions.
- An App opens only to the Place roles it lists.
Builds
- Release builds align loops on 64 bytes, so performance no longer moves with unrelated changes of code
layout.
Full Changelog: v1.0.2...v1.0.4
Small core, long life.
v1.0.2
openglacier Core v1.0.2 — antaa palaa
A faster query engine: typed batches, partial documents and smarter joins.
v1.0.2 is a performance release. Queries return the same rows; most of them do less work to get there.
Query engine
- Typed batches: row-local stages,
group,unwindand pivot cells run on batches of typed columns, with a
typed group key and dense measure states. - Partial documents: a query decodes only the fields it reads; Top-N ranks on partial documents and hydrates
the winners only. - Top-N is pushed through the stages that keep rows as they are.
- Joins: a
lookupon equality is served by a hash join, and a bounded lookup indexes only the joined rows
it can match (semi-join). - Ordered scans stream from the resident primary index instead of sorting every entry; samples are drawn
from the primary index. - Constant expressions are folded; row-local stages are compiled once; group measures fold from borrowed storage
values; a same-collectionunioncounts with one shared scan. - The memory governor reads available memory without sampling
/proc.
Language
- Several fields and expressions as pivot values.
\uXXXXescapes in strings.nullsorts like a missing field instead of failing.
Fixes
- The connection queue.
- A routing invariant violation answers an error instead of stopping the daemon.
Full Changelog: v1.0.1...v1.0.2
Small core, long life.
v1.0.1
openglacier Core v1.0.1 — antaa palaa
The Core as a library, one expression evaluator, and fixes.
Changes
openglacier-coreis a library with theogdandogclibinaries on top: distributions such as
GlacierDB build on it.- The
llama.cppcommon/chat bridge moves to a crate of its own,openglacier-llama-common-chat. - One expression evaluator for every stage, with its functions and bounded stages gathered in one place.
- The daemon's query plumbing and the engine's virtual collections are smaller; shared helpers live in
helpers.rs.
Fixes
- Random bytes on Windows no longer read
/dev/urandom. - A public Place behaves as expected on a Core without authentication.
- A query ending in
intois authorized on the collection it writes, and the collection it reads must be
readable too. - The flow of rows between pipeline stages.
Full Changelog: v1.0.0...v1.0.1
Small core, long life.
v1.0.0
openglacier Core v1.0.0 — antaa palaa
First stable release.
openglacier Core v1.0.0 carries the code name antaa palaa. It means one thing: the core architecture
is now stable enough to build on.
This milestone comes after an extended period of real-world use and hostile testing: continuous fuzzing,
sustained read/write workloads, failure injection, storage corruption and I/O failure testing, crash recovery,
backup and restore validation, and a large integration test suite.
It has also been exercised across architectures and generations of hardware, from the Raspberry Pi 3 and 4 to
the Odroid XU4 and a Fairphone 2. Resources are valuable.
In this release
- Glacier, the native persistent storage engine (
OGD_STORAGE=glacier);ogdstill starts in memory when
no storage is set, GlacierDB on Glacier. - One package name: the crate is
openglacier-core, the binariesogdandogcli. install.shinstalls a release archive on Linux and macOS.- A default bootstrap password for a first local start, to be changed on any shared node.
- Release builds for every target through cross, with one pinned image per target.
- The code went through a 30-day consolidation pass: shared code staged, clippy clean, tests rewritten,
dependencies audited.
Full Changelog: v0.80.2...v1.0.0
Small core, long life.
v0.80.2
openglacier Core v0.80.2
Native tool calling, GPU-aware local inference, and a much more deliberate Agent execution loop.
openglacier Core v0.80.2 deepens the local AI path introduced in v0.80.0.
The LLM runtime now integrates more directly with llama.cpp common/chat for tool-aware prompt rendering and response parsing, adds explicit CPU/CUDA device selection, exposes thinking policy, and can reuse prompt-prefix state across multi-step Agent runs.
The Agent also moves away from an ad-hoc model-output protocol toward structured tool definitions and native tool calls.
Database-oriented runs gain collection description, bounded evidence gathering, multiple read-only analysis queries, separate synthesis budgets, and more careful context management.
Highlights
Tool calling becomes a first-class LLM contract
llm.generate can now receive structured tool definitions and tool-choice policy.
The request model supports:
tools
toolChoice
messages[].toolCalls
messages[].toolCallId
cacheKey
and generation can emit structured:
toolCall
events alongside normal text.
The Agent no longer needs to instruct a model to manufacture a private JSON envelope for every tool invocation.
llama.cpp common/chat integration
v0.80.2 introduces a native bridge around the llama.cpp common/chat implementation.
The bridge is used to:
- apply model chat templates;
- pass structured tool definitions;
- apply tool-choice policy;
- preserve generation prompts;
- expose stop conditions and parser metadata;
- parse generated content;
- extract native tool calls;
- separate reasoning content when supported.
Conceptually:
OpenGlacier messages + tools
│
▼
llama.cpp common/chat
│
▼
model-specific prompt
│
▼
generation
│
▼
common/chat parser
│
├── assistant content
└── structured tool calls
This delegates model-specific chat behavior to the same machinery used by llama.cpp instead of rebuilding template conventions independently in Rust.
Structured tool calling
The LLM request contract now supports tool definitions containing:
name
description
parameters
Tool choice can be:
auto
none
required
Assistant history can also carry structured tool calls, while tool results are linked back through a tool-call id.
This makes multi-turn tool use representable as normal chat history rather than as opaque text.
Process-safe tool parsing
The current runtime uses common/chat for prompt rendering and native tool-call parsing.
For the pinned llama.cpp generation path in this release, token-level tool grammar installation is intentionally not relied upon when it can threaten process stability.
Tool-aware templates and the common/chat parser remain active.
The practical tradeoff is:
native tool format + parser
instead of:
unsafe in-process grammar enforcement
until the underlying grammar path is safe for the daemon.
Thinking policy
Local generation now has an explicit thinking policy:
auto
on
off
configured through:
OGD_LLM_THINKING
auto keeps the runtime policy tool-safe:
- native/template behavior for ordinary turns;
- thinking disabled for tool-oriented turns.
on and off can force the behavior when a model and template support it.
The selected policy is also exposed through LLM status.
CPU and CUDA device selection
The local LLM runtime can now choose its execution device explicitly.
Configuration is available through:
OGD_LLM_DEVICE
with:
auto
cpu
cuda
auto uses GPU offload when the runtime reports a usable CUDA device and otherwise falls back to CPU.
cpu disables GPU layers explicitly.
cuda requires a usable CUDA backend and visible CUDA device, and fails with an actionable error when that requirement cannot be satisfied.
GPU layer control
GPU offload can be tuned with:
OGD_LLM_GPU_LAYERS
Accepted values are:
auto
all
<number>
This allows deployments to leave layer placement to llama.cpp, offload the complete supported model, or request a specific layer count.
CUDA build features
CUDA support remains a compile-time choice.
New feature profiles include:
cuda
cuda-no-vmm
full-cuda
For example:
cargo build --release --features full-cudaA binary built without a usable GPU backend can still run the LLM service on CPU.
Explicit:
OGD_LLM_DEVICE=cuda
is reserved for deployments that require CUDA rather than merely preferring it.
Prompt-prefix reuse
Multi-step Agent runs often send the same long prompt prefix repeatedly:
system instructions
conversation
previous tool history
followed by a relatively small new suffix.
v0.80.2 can snapshot and reuse ephemeral llama.cpp sequence state for these repeated prefixes.
Conceptually:
turn 1
[ stable prefix ][ new content ]
│
└── capture sequence state
turn 2
[ same stable prefix ][ different suffix ]
│
├── restore cached state
└── decode suffix only
This cache is designed for reuse inside an Agent run rather than as durable conversation memory.
Bounded prefix cache
The host-memory budget is controlled with:
OGD_LLM_PREFIX_CACHE_MAX_BYTES
The default budget is:
1 GiB
Setting it to:
0
disables prefix-state caching.
Generation statistics can report:
cachedPromptTokens
so callers can observe how much prompt work was reused.
A more capable Agent tool contract
The Agent tool set now contains:
database.collections
database.describe
database.query
files.list
The new:
database.describe
tool allows the Agent to inspect a schemaless collection before inventing field names.
It returns the scoped collection size together with field paths and JSON types observed from a bounded prefix of visible documents.
Observed fields are treated as evidence, not as a strict schema guarantee.
Better database analysis
The Agent now distinguishes between:
looking at a few rows
and:
reasoning about a collection
For summaries, distributions and analytical questions, it can:
- discover or describe the collection;
- issue targeted read-only queries;
- gather compact evidence;
- perform a final synthesis turn.
This avoids treating:
limit 20
as if those 20 documents represented the complete collection.
Native query discipline
Agent database access continues to use the openglacier pipeline language.
Queries must start from the native DSL shape:
on <collection>
For example:
on orders
| group status
| sort count desc
| limit 20
The Agent is explicitly guided away from:
SQL
MongoDB syntax
JSON query objects
and from mutating operations.
System collections remain inaccessible through Agent database tools.
Bounded analytical loops
Database analysis now has its own query budget.
The default maximum is:
4
and can be configured with:
OGD_AGENT_MAX_DATABASE_QUERIES
The upper accepted bound is deliberately finite.
This gives the Agent room to gather more than one piece of evidence without allowing an open-ended query loop.
Separate planning and synthesis budgets
Tool-selection turns and final-answer turns do not have identical needs.
v0.80.2 therefore adds a separate synthesis budget.
The default final synthesis allowance is larger than the normal planning budget and can be configured through:
OGD_AGENT_SYNTHESIS_MAX_TOKENS
An explicit request-level maxTokens remains a hard cap.
This lets short tool-planning turns stay compact while giving the final answer enough room to summarize the evidence.
Smaller tool context
The default maximum tool-result context is reduced from:
32 KiB
to:
8 KiB
Database evidence is compacted even more aggressively between analytical turns.
The Agent keeps a small evidence ledger instead of carrying every verbose tool response indefinitely.
This is particularly important for small local models with limited context windows.
Adaptive context handling
When a synthesis request exceeds the model context window, the Agent can now adapt.
It can:
- reduce the generation budget;
- compact database-derived evidence;
- shrink retained tool output;
- retry with a smaller context footprint.
Only tool-derived database context is compacted by these emergency paths.
The user conversation and execution scope remain conceptually distinct from this temporary evidence reduction.
More deliberate tool choice
The Agent can now narrow the tool set and tool-choice policy according to the request.
Examples include requiring:
database.collections
for collection discovery, or:
database.describe
before a schema-oriented answer.
Analytical requests can require actual:
database.query
execution before synthesis.
Final synthesis turns use:
toolChoice = none
so the model is asked to answer from evidence rather than start another tool loop.
Agent provider timeout
Delegated Agent capability calls can legitimately wait longer than ordinary requ...
v0.80.0
openglacier Core v0.80.0
Compile-time capability builds, local LLM and Agent services, and a more capable concurrent CLI.
openglacier Core v0.80.0 changes how the daemon is assembled.
The Core can now be built from explicit capability families instead of always carrying every service implementation in one binary.
The default build stays focused on the local database path:
databaseauthcli
while additional services can be compiled only when they are actually needed:
fileseventsdata-importllmagentfabricfiles-watchcli-tui
This release also introduces a local GGUF LLM runtime backed by llama.cpp, a stateless Agent orchestration layer, streaming LLM and Agent operations, cancellation and queueing, and an optional terminal UI for concurrent interactive work.
Highlights
Build only the Core a node needs
Cargo features now describe which implementation families physically exist in a binary.
Runtime capabilities remain a separate concern.
Conceptually:
Cargo features
│
▼
compiled services
│
▼
OGD_NODE_CAPABILITIES
│
▼
enabled services
│
▼
published operations
A capability therefore has two distinct questions:
was it compiled?
and:
is it enabled on this node?
This makes small, purpose-specific binaries possible without changing the operation model.
Compile-time capability profiles
The default feature set is now:
database
auth
cli
This is intended for a local database node with authentication and the administrative CLI.
Additional service families are explicit opt-ins.
For example:
cargo build --release --features files,eventsor:
cargo build --release --features llm,agentA broad daemon build remains available through:
cargo build --release --features fullfull compiles the historical service families together with the optional extension providers.
Compilation does not automatically enable every compiled service at runtime.
In particular, extension capabilities such as:
data.import
llm
agent
remain explicit runtime choices.
Build-aware operation catalogue
The canonical operation catalogue now understands build composition.
Operations can describe:
- their provider capability;
- the implementation family required to compile them;
- whether they depend on the internal database engine;
- whether the implementation exists in the current binary;
- whether the operation should be published by the current node.
This keeps operation names and wire contracts centralized while allowing different binaries to expose different implementation sets.
Core operations such as:
ping
core.health
core.operations
node.status
remain independent from optional provider families.
The result is a cleaner separation between:
protocol contract
compiled implementation
and:
runtime publication
Local LLM capability
v0.80.0 introduces a local LLM provider backed by:
llama.cpp
GGUF
The capability is compile-time optional through:
llm
and exposes three operations:
llm.status
llm.generate
llm.cancel
llm.generate is streamed.
Generated text is emitted incrementally rather than being buffered until the complete answer is available.
LLM scheduling and cancellation
The local runtime includes a bounded scheduler.
Each generation receives a runId and can begin in either:
running
or:
queued
state.
The scheduler controls:
- maximum parallel generations;
- queue capacity;
- ownership of runs;
- queued cancellation;
- active cancellation.
This prevents an embedded model from becoming an unbounded source of concurrent work.
A queued or running generation can be cancelled with:
llm.cancel
LLM configuration
The first local runtime can be configured through environment variables including:
OGD_LLM_MODEL
OGD_LLM_CONTEXT_SIZE
OGD_LLM_THREADS
OGD_LLM_MAX_TOKENS
OGD_LLM_SEED
OGD_LLM_MAX_PARALLEL
OGD_LLM_QUEUE_SIZE
OGD_LLM_CHAT_TEMPLATE
A model is optional at process startup.
Without OGD_LLM_MODEL, the capability can remain compiled while reporting itself as unconfigured.
When configured, the runtime loads the GGUF model locally and uses the model chat template, or an explicit template supplied through configuration.
Stateless Agent capability
v0.80.0 also introduces the first openglacier Agent service.
The Agent is deliberately stateless.
It owns the reasoning and tool loop, but it does not own the underlying capabilities.
Instead, it invokes services supplied by the host.
Conceptually:
Agent
│
├── llm.generate
│
├── database collections
│
├── database query
│
└── files
The first tool set contains:
database.collections
database.query
files.list
Database queries issued by the Agent are restricted to read-only execution.
Mutating query plans are rejected before reaching the database capability.
Inherited execution scope
The Agent does not invent its own Place or AppInstance context.
The execution scope is inherited from the request.
That means tool calls do not carry arbitrary scope identifiers chosen by the model.
Conceptually:
request
│
▼
validated Place / AppInstance
│
▼
Agent run
│
▼
tool calls inherit that scope
This keeps Agent orchestration inside the same authorization and execution model as the rest of the Core.
Local or delegated capabilities
The Agent does not assume that its tools are local.
A standalone daemon can invoke local capabilities directly.
A fabric node can delegate the same capability calls through Gateway.
The Agent loop therefore depends on operation contracts rather than concrete backend ownership.
This is important for keeping AI orchestration out of the database kernel itself.
New Agent operations
The Agent service exposes:
agent.status
agent.run
agent.run is streamed.
A run can emit progress around:
- LLM steps;
- tool calls;
- tool results;
- final messages.
Process-wide Agent limits can be configured with:
OGD_AGENT_MAX_STEPS
OGD_AGENT_LLM_MAX_TOKENS
OGD_AGENT_MAX_TOOL_BYTES
The service retains limits, not conversation state.
Concurrent ogcli
The interactive CLI can now run requests concurrently.
Long-running operations no longer have to monopolize the prompt while they stream output.
Background work is identified by a local job id and can continue while new commands are entered.
This is particularly useful for:
llm.generate
agent.run
long-running queries
streaming operations
The normal REPL remains intentionally thin: it speaks the daemon protocol and does not duplicate server behavior.
Optional terminal UI
A new optional TUI can be compiled with:
cli-tui
and started with:
ogcli --tuiThe TUI uses the same concurrent request model as the regular CLI.
It adds:
- multiple jobs;
- tabs;
- tiled views;
- per-job status;
- scrolling;
- focus switching;
- LLM cancellation.
The interface is therefore a view over the protocol rather than a second execution model.
Capability-oriented daemon composition
Service implementations are now explicitly grouped around capabilities.
Examples include:
database
auth
files
events
data.import
llm
agent
Infrastructure features such as:
fabric
files-watch
cli
cli-tui
remain distinct from published service capabilities.
This helps keep three concerns separate:
database kernel
service provider
user interface
A database-only build should not need to carry an LLM runtime.
An LLM provider should not need to become a database server.
A CLI should not define server semantics.
Compatibility
The operation protocol remains capability-oriented, but build composition changes materially in v0.80.0.
The default Cargo build now contains:
database
auth
cli
rather than every optional service family.
Applications or deployment scripts that require files, events, fabric, data import, LLM, Agent or TUI support should enable the corresponding Cargo features explicitly.
For a broad daemon build:
cargo build --release --features fullRuntime capability selection still applies after compilation.
An operation cannot be enabled if its implementation was not compiled into the binary.
Examples
Default local database build:
cargo build --releaseBroad daemon build:
cargo build --release --features fullLocal LLM and Agent build:
cargo build --release --features database,auth,cli,llm,agentStart a configured local LLM provider:
OGD_LLM_MODEL=./models/model.gguf \
OGD_NODE_CAPABILITIES=database,llm,agent \
cargo run --release --features database,auth,cli,llm,agent --bin ogdInspect the compiled and published operation surface:
.core.operations
Start the optional terminal UI:
cargo run --release --features cli-tui --bin ogcli -- --tuiIn short
v0.80.0 makes openglacier Core more modular at the binary level.
The visible additions are substantial:
compile-time capabilities · local LLM · stateless Agent · concurrent CLI · optional TUI
but th...