Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
[0.3.2] - 2026-04-05
Added
ReliabilityContextdataclass instroma.middleware— per-run bundle of all reliability primitives, decoupled fromStromaRunnerexecute_step()standalone async function — the full reliability loop (contracts, cost, retries, checkpoints, tracing) as a freestanding primitive usable withoutStromaRunnerStromaStepclass — paradigm-agnostic decorator/wrapper backed byexecute_step(), equivalent toStromaRunner.node()but independent of any execution strategyStepInterceptor,LoopAdapter,TurnAdapterprotocols instroma.adapters.base— adapter shapes for agentic-loop, conversation-driven, and step-wrapping paradigms- Step aliases for paradigm-neutral naming:
StepContract,StepViolation,StepUsage,StepContext,StepHooks,stroma_step, andTraceEvent.step_idproperty FallbackPolicyandresolve_model()for budget-aware model downgrade during executionStromaRunner.with_model_fallback()fluent builder for configuring model fallback rulesRunConfig.model_fallbacksfield for specifying fallback policies
Changed
StromaRunnerinternals refactored to useReliabilityContext— no public API changes, all existing behavior preserved
[0.3.1] - 2026-04-05
Added
FrameworkAdapterProtocol instroma.adapters.base— shared contract that all framework adapters implementextract_state_dict()moved tostroma.adapters.baseas framework-agnostic utility (re-exported fromstroma.adapters.langgraphfor backwards compatibility)CrewAIAdapterand@stroma_crewai_stepdecorator for wrapping CrewAI Flow methods with contract validationstroma[crewai]optional install extra (crewai>=0.70)- Conditional adapter export in
stroma.adapters.__init__for CrewAI
[0.3.0] - 2026-04-05
Added
- Per-node timeout support via
RunConfig.node_timeouts— wraps node execution withasyncio.wait_for, raisingTimeoutError(classified asRECOVERABLE) when exceeded StromaRunner.with_node_timeouts()fluent builder method- Retry support for parallel nodes —
_execute_parallel_nodenow uses the same_handle_failureretry/backoff path as sequential nodes
Fixed
CostTracker.record()now preservesmodelandoutput_tokensfields when accumulating retries (previously dropped silently)
Changed
- Parallel node failure tests updated to expect
PARTIAL(retries exhausted) instead ofFAILED(immediate), matching the new retry behavior - Added regression tests for
CostTracker.record()field accumulation (model,output_tokens,Nonefallback) - Added tests for per-node timeout behavior (retry on timeout, exhaustion, fluent builder)
- Updated parallel execution and retry/failure tutorial docs to cover timeouts and parallel retries
Removed
RunConfig.model_hintsfield — was accepted but never read by the runner; removed to avoid implying unimplemented capability- Duplicate
StromaRunner._unpack_outputstatic method — consolidated to module-level_unpack_output
[0.2.7] - 2026-04-02
Changed
- Project description unified to "Reliability primitives for agent pipelines." across pyproject.toml, mkdocs.yml, README, and docs homepage
[0.2.6] - 2026-04-02
Added
- Per-child contract validation in
parallel()— each child's output is validated against its declared contract before merging - Full instrumentation for parallel nodes: hooks (
on_node_start/on_node_success/on_node_failure), cost tracking, budget checking, and checkpointing
Changed
- Parallel failure classification now uses the runner's classifiers instead of hardcoding
AMBIGUOUS - Rewrote "Stroma vs. LangGraph" page as an honest comparison with known limitations section
Removed
FailurePolicy.fallback_node_id— was declared in the model but never implemented in the runner; removed to avoid implying unimplemented capability
[0.2.5] - 2026-04-02
Added
DeepAgentsAdapterand@stroma_deepagents_nodedecorator for wrapping deepagents graphs with contract validation and cost trackingstroma[deepagents]optional install extra (deepagents>=0.4.0,langgraph>=0.2)- DeepAgents adapter tab in homepage install section
- DeepAgents tutorial and API reference docs
- Conditional adapter exports in
stroma.adapters.__init__for both LangGraph and DeepAgents
Changed
- Homepage rewritten with dbt analogy framing and crash/resume/diff hero example
- README tagline updated to match new homepage positioning
- All
pip installreferences across docs, README, source docstrings, and examples replaced withuv add - README Development section now uses
uv sync --extra devinstead ofuv pip install -e CLAUDE.mdexpanded with project layout, quality gate commands, optional extras pattern, testing, and docs conventions
[0.2.4] - 2026-04-01
Added
- Quickstart page with contract, retry, checkpoint/resume, and trace demos
- "Stroma vs. LangGraph" comparison page
- Stability section in Concepts (stable / beta / experimental primitives)
- Homepage before/after section and focused "what you get" bullets
- Runnable examples:
simple_pipeline.py,retry_demo.py,checkpoint_resume.py,langgraph_integration.py - AGENTS.md with Claude Code agent instructions
Fixed
RunConfigAPI reference now shows per-field descriptions- OTel example in
extending.mdno longer silently drops spans when a node is retried - README "What You Get" bullets now include the fluent builder API
parallel()contract bypass documented as an explicit warning admonition in Conceptson_node_successtokens_usedargument semantics documented (input + output tokens,0if unreported)KNOWN_MODELSpricing table added to Concepts page so models and prices are discoverable without reading source- README Install section now states the Python 3.12+ requirement
- Home page Next Steps section replaced broken table-as-cards with a clean bullet list
- API reference for
stroma_nodenow explains when to use it vs@runner.node - Softened vs-LangGraph tone, added side-by-side capability table
[0.2.0] - 2026-04-01
Added
KNOWN_MODELSpricing dict andestimate_cost_usd()for computing cost from model name and token countsAsyncCheckpointStoreprotocol,AsyncInMemoryStore, and asyncRedisStorefor non-blocking checkpoint I/OSyncRedisStorealias for the original synchronous Redis storeNodeHooksdataclass withon_node_start,on_node_success, andon_node_failureasync callbacksRunConfig.node_policiesfor per-node retry policy overridesRunConfig.contextshared dict passed to nodes that accept a second argumentparallel()fan-out primitive for running nodes concurrently with merged output- Per-run
logging.LoggerAdapterwithrun_idin structured extra fields - Fluent builder methods on
StromaRunner:with_redis(),with_budget(),with_classifiers(),with_hooks(),with_context(),with_policy_map(),with_node_policies() StromaRunner.quick()now accepts an explicithookskeyword argument- "Extending Stroma" documentation page covering custom checkpoint backends, failure classifiers, OTel integration, and composing all extension points
Changed
NodeUsagenow carriesmodelandoutput_tokensfields;_unpack_outputsupports 2/3/4-tuple and bare dict returnsCheckpointManager.checkpoint,.resume,.clearare now async; call sites in runner updatedStromaRunner.quick()defaults toAsyncInMemoryStoreinstead ofInMemoryStoreContractViolation.__str__now surfaces field-level Pydantic errors (up to 5, then truncated)CostTracker,RetryBudget,ExecutionTraceinstantiated per-run inrun()instead of__init__, preventing state accumulation across calls_handle_failurelooks up per-node policy overrides before falling back to globalpolicy_mapLangGraphAdapter._wrap_noderaisesTypeErrorwith the function name when contract is missing, instead of a silentAttributeError- Runner logger calls in
_execute_nodeand_handle_failureuse per-runLoggerAdapter, removing inlinerun_idfrom format strings
[0.1.1] - 2026-03-31
Fixed
UnboundLocalErrorguard forinput_modelin runner- Retry jitter using
random.uniform(0, backoff_seconds) - Redis key prefix changed from
armature:tostroma: ExecutionTrace.diff()now excludestimestamp_utcandduration_msLangGraphAdapter._wrap_nodereturns validated model outputNodeContextandRetryBudgetadded to__all__pytest-asynciofloor version pinned to>=0.23
[0.1.0] - 2026-03-30
Added
- Initial release
ArmatureRunnerfor sequential node execution with retriesContractRegistryandNodeContractfor input/output validationCheckpointManagerwithInMemoryStoreandRedisStorebackendsCostTrackerandExecutionBudgetfor resource trackingFailureClass,FailurePolicy, andclassify()for failure handlingExecutionTraceandTraceEventfor execution recordingLangGraphAdapterfor integrating with LangGraph pipelines