Repository navigation
Releases: datalium/strata
Release list
Datalium Strata 0.9.0-preview.1
The first version with a number, and the first one published: on nuget.org, on crates.io and as a GitHub release with the strata CLI. Before it, applications pinned a commit of this repository.
Why 0.9 and why a preview: the 2026-09-21 evaluation called the state of that day 0.3.0 and set gates for what follows. The gate for 0.5.0 (a real application has run on it and its findings are fixed) has been met. Of the four for 0.9, crash-durable checkpointing, storage hardening and benchmarks are built, and this preview, published on both registries, is the fourth.
Built by the Datalium Strata team, developed privately from June 2026 until this release.
The packages
| .NET | Rust | What it is |
|---|---|---|
Datalium.Strata |
datalium-strata, datalium-strata-macros |
The engine: typed state graphs, compile-time validation, streaming, interrupts and resumes, waits and timers, parallel groups and maps, subgraphs, retries, tools generated at compile time, durable execution. The .NET package includes the [StrataTool] source generator. |
Datalium.Strata.Storage |
datalium-strata-memory |
Checkpoint and history stores: in-memory, SQLite, Postgres, Redis. |
Datalium.Strata.Cloud |
datalium-strata-cloud |
The Strata Cloud checkpoint store, decisions client and decision worker. |
Datalium.Strata.Hosting |
datalium-strata-host |
Registration and settings (.NET), the wake, recovery and retention drivers, health. |
Datalium.Strata.AI |
datalium-strata-ai |
Model calls and agents: chat from a node, the model node, the agent loop with typed answers, model routes, embeddings and the long-term memory helper. |
A .NET application usually references Datalium.Strata.Hosting alone: it brings the other four, and the source generator with them.
Changes before this version
For applications that pinned a commit of this repository before there were versions. Newest first. Each entry names the design document with the detail.
- A tool's own
ArgumentExceptionis no longer mistaken for bad arguments (design/20,design/44). .NET's generated dispatch now throwsToolArgumentsException(Datalium.Strata.Tools, anArgumentException, withToolNameandProblems) for arguments it can't bind, before the tool runs.StrataAgentrefuses only that back to the model. Before, it also caught a tool's ownArgumentExceptionorJsonException(a domain check, say), hiding a real failure; that is now the tool's failure, which fails the node or, underToolFailures.ReturnToModel, goes back astool 'x' failed: ….- The model is told what to fix, in the same words in both engines:
invalid arguments for tool 'lookup': argument 'orderId' must be a string,… argument 'count' is missing,… the arguments aren't a JSON object. Before, .NET passed on the parser's message, which named a generated record and a line number. The rule isToolArguments.Problems/ Rusttools::argument_problems, pinned by the new shared fixtureschema/fixtures/tools/argument-problems.json; Rust's#[strata_tool]now uses it forToolArgumentParseFailure. - .NET's generated dispatch refuses a missing required argument, and null for a non-nullable parameter, as the manifest says and as Rust always did. Before, the tool ran with
nullor0. - The registry's
error.typeinvalid_argumentsnow means only this. A tool's ownJsonExceptionis reported by its type name. - Compatibility: a tool that relied on getting
nullor0for an omitted required parameter is now refused; give the parameter a default, or make it nullable. Code that matched an agent's refusal text on the parser's words sees the new words. A hand-writtenIStrataToolProviderthat threwJsonExceptionorArgumentExceptionfor bad arguments should throwToolArgumentsExceptionto keep the agent's refusal.
- The model is told what to fix, in the same words in both engines:
- An agent's options can change by turn (
design/44).StrataAgentOptions.ConfigureTurn(Action<AgentTurn, ChatOptions>) and Rust'sAgentOptions::with_configure_turn(Fn(&AgentTurn, &mut ChatRequest)) change one turn's copy of the options before its model call, after the agent has set the tools and response format.AgentTurngives the turn's number, the tool turns before it, the repairs so far and whether it is a repair. For example, a tool call can be required on the first turn only; withChatOptions.ToolMode/tool_choiceit applied to every turn, so the model could never answer. New .NETAgentTurn; RustAgentTurn,ConfigureTurn. - A cancelled streaming run no longer hangs on a full channel (
design/17). The engine's ownNodeEnd,RetryandErrorchunks waited for room with no token. A consumer that stopped reading and then cancelled the run (anawait foreachoverReadAllAsync(token)with the run's token, say) could leave the run blocked forever, its completion never finishing. Now those chunks are dropped once the level's token fires, asNodeStartalready was. Both engines. - .NET: a handler cancelled while it waits on a full stream sees
OperationCanceledException.EmitTokenAsync/EmitDiagnosticAsyncusually threwChannelClosedExceptioninstead, because the run ended and closed the channel before the handler's token reached the write. Code that caughtOperationCanceledExceptionmissed it. - .NET's recovery count is public (
design/33, SG-39).RecoveryCount(Datalium.Strata.Graph) withMetadataKey(strata.recoveries) andOf(checkpoint)is nowpublic, as Rust'srecovery::RECOVERIES_KEYandrecoveries_ofalready were. It is how many times a thread has been recovered since a node last committed.RecoverOptions.MaxRecoverieslimits it for the driver only;RecoverAsyncandRecoverStreamingalways recover, so an application that recovers threads itself readsRecoveryCount.Ofon the latest checkpoint and stops at its own limit, instead of reading the key by name. No behaviour or wire format changed. - Exported definitions mark interrupt boundaries (
design/48, SG-37).ToDefinition()/to_definition()now writes"interrupt": { "timeout_ms": … }on every interrupt boundary that is a node: the timeout in whole milliseconds, ornullfor a boundary without one. A plain node, a parallel group, a subgraph node or a map node can each be a boundary; a wait node can't. A boundary's routes are still itson_reject/on_timeoutedges. A level with a boundary is definitionschema_version1.6.0, a superset of1.5.0; every other level exports exactly as before. The shared validator gainsSTRATA_ERR_BOUNDARY_IN_MAPfor a boundary in a map's template, which.compile()already refused.strata graph validate,check_shapeand .NET'sToTopology()refuse (exit 2) aninterruptbelow1.6.0or on a wait node, a negativetimeout_ms(.NET; Rust's type refuses it), and, at a1.6.0level only, anon_rejectedge from a node that isn't a boundary or anon_timeoutedge from a node with no timeout.strata graph viewannotates each boundary (Approve: interrupt boundary, rejects to Abort, times out after 30m to Escalate, or…, then the thread endswhen a timeout has no route). New .NETGraphNodeDetail.Interrupt(GraphInterrupt(TimeoutMs)),GraphNodeDefinition.Interrupt(GraphInterruptDefinition),GraphDefinition.BoundaryVersion,ValidationErrorKind.BoundaryInMap; RustGraphNodeDef.interrupt(GraphInterruptDef),schema::BOUNDARY_GRAPH_SCHEMA_VERSION,ValidationErrorKind::BoundaryInMap. Compatibility: an exported graph with a boundary changes bytes and version, so a snapshot of one changes, and an older CLI refuses it (unsupported schema_version '1.6.0'): upgrade the CLI that gates definitions first. A RustmatchonValidationErrorKindnaming every variant breaks. Checkpoints are unchanged. New wire format: graph definition1.6.0. - The .NET Redis memory store's search no longer drops records (
design/45). On Redis 8, anFT.SEARCHthat returns the documents' fields can leave documents out of its reply, though the index has them: about one search in twenty-five straight after a write under load missed one record or all of them, which the read-your-writes fix couldn't help.SearchAsyncnow asks the index for keys and distances only and reads each candidate's hash in one pipeline, as the Rust store always has, and checks it against the search again. A search costs one more round trip. No API or wire format changed. - **A ...