Releases: LunarCommand/openarmature-python
v0.6.0
What's Changed
- docs: README install section for v0.5.0 PyPI publish by @chris-colinsky in #31
- docs: ship the openarmature docs site (Phase A) by @chris-colinsky in #32
- ci: rename CF Pages project to openarmature-python-docs by @chris-colinsky in #33
- docs: flip site_url to apex openarmature.ai by @chris-colinsky in #34
- docs: drop mike version provider for pre-1.0 by @chris-colinsky in #35
- docs: README rework + small docs-site polish by @chris-colinsky in #36
- chore: add PEP 621 classifiers to pyproject.toml by @chris-colinsky in #37
- chore: pin GitHub Actions to SHAs, add dependabot by @chris-colinsky in #38
- docs: scrub em dashes, polish landing + nav by @chris-colinsky in #41
- chore(deps): bump softprops/action-gh-release from 2.6.2 to 3.0.0 by @dependabot[bot] in #39
- chore(deps): bump github/codeql-action from 3.35.4 to 4.35.4 by @dependabot[bot] in #40
- feat(llm): structured output (proposal 0016) by @chris-colinsky in #42
- chore: bring examples under pyright by @chris-colinsky in #43
- feat(llm): image content blocks (proposal 0015) by @chris-colinsky in #44
- feat(prompts): prompt-management core (proposal 0017) by @chris-colinsky in #45
- feat(checkpoint): state migration for checkpoints (proposal 0014) by @chris-colinsky in #46
- feat(graph): parallel branches (proposal 0011) by @chris-colinsky in #47
- chore(release): v0.6.0 by @chris-colinsky in #48
- fix(release): install examples dep group in release workflow by @chris-colinsky in #49
New Contributors
- @dependabot[bot] made their first contribution in #39
Full Changelog: v0.5.0...v0.6.0
v0.5.0
What's Changed
- test: phase 0 conformance harness — typed parser for all 68 fixtures by @chris-colinsky in #7
- test: handle model instances in fixture discriminators by @chris-colinsky in #8
- graph: spec v0.6 observer pair model (proposal 0005) by @chris-colinsky in #9
- chore: support plural subgraphs: form, pull spec v0.8.1 by @chris-colinsky in #10
- ci: tag-driven release pipeline with TestPyPI RC track by @chris-colinsky in #11
- chore: bump to 0.4.0rc0 for release pipeline smoke test by @chris-colinsky in #12
- docs: add RELEASING.md, bump workflow actions to Node 24 by @chris-colinsky in #13
- graph: spec v0.4 middleware (proposal 0004) — phase 2 by @chris-colinsky in #14
- graph: phase 2 polish — review followups by @chris-colinsky in #15
- graph: spec v0.4 fan-out runtime (proposal 0005 PU side) — phase 3 by @chris-colinsky in #16
- llm: spec v0.8 llm-provider (proposal 0006) — phase 4 by @chris-colinsky in #17
- checkpoint: spec v0.8 checkpointing (proposal 0008) — phase 5 by @chris-colinsky in #18
- observability: spec v0.7 OTel mapping (proposal 0007) — phase 6.0 by @chris-colinsky in #19
- observability: PR #19 round-7 review followups by @chris-colinsky in #20
- sync spec_version pin to 0.8.2 by @chris-colinsky in #21
- observability: phase 6.1 concurrency-safe observer (PR-A) by @chris-colinsky in #22
- observability: phase 6.1 PR-B — logs SDK migration + filter bug fix by @chris-colinsky in #23
- observability: phase 6.1 PR-C — 4 conformance fixtures by @chris-colinsky in #24
- graph: phase 6.1 PR-C.1 — proposal 0012 + v0.9.0 by @chris-colinsky in #25
- observability: phase 6.1 PR-C.2 — proposal 0013 + v0.10.0 by @chris-colinsky in #26
- observability: phase 6.1 PR-C.3 — prepare_sync + fixture 010 by @chris-colinsky in #27
- release: prep 0.5.0rc1 by @chris-colinsky in #28
- ci: release workflow needs --all-extras for type checks by @chris-colinsky in #29
- release: 0.5.0 by @chris-colinsky in #30
Full Changelog: v0.4.0...v0.5.0
v0.4.0
Spec v0.3.1 / proposal 0003: node-boundary observer hooks.
External code can now observe execution as it happens — the control-side equivalent of the data-side trace field pattern.
New public API
NodeEvent(frozen dataclass):node_name,namespacetuple,step,pre_state/post_state,error,parent_states. Exactly one ofpost_stateorerroris populated per event.ObserverProtocol: async callable receiving aNodeEvent. The parameter is positional-only so conformance isn't tied to a parameter name.CompiledGraph.attach_observer(fn) -> RemoveHandlefor graph-attached observers;invoke(state, observers=...)for invocation-scoped.CompiledGraph.drain()— awaits delivery of every event dispatched by prior invocations of this graph. Required for short-lived processes (CLIs, scripts, serverless).
Delivery semantics
- Strictly serial within an invocation: no two observers process the same event concurrently; no observer sees event N+1 until everyone has finished N.
- Order: graph-attached (outermost → innermost), then invocation-scoped — both in registration order.
- Async-from-graph:
invoke()returns when the graph reaches END regardless of queue state. - Observer exceptions are caught and reported via
warnings.warn— they don't break siblings, subsequent events, or the graph run. - Subgraph-internal events bubble up: the subgraph wrapper itself stays observer-transparent. Step counter spans the subgraph boundary;
namespaceandparent_statesextend.
Other changes
- CI workflow added at
.github/workflows/ci.yml(ruff + ruff-format + pyright + pytest). - Spec submodule pinned at v0.3.1 (corrigendum to fixture 013's YAML syntax).
See the proposal for design rationale.
v0.3.0
Spec v0.2 / proposal 0002: explicit subgraph input/output mapping.
ExplicitMapping(inputs=..., outputs=...)projection strategy as a built-in alternative to writing a customProjectionStrategy.- New
mapping_references_undeclared_fieldcompile error category forinputs/outputsthat name fields absent from the relevant schema. ProjectionStrategy.validateis an optional duck-typed compile hook — declarative strategies (ExplicitMapping) expose it; imperative custom projections aren't forced to write a no-op.- Spec submodule pinned at v0.2.0.
See the proposal for design rationale.
v0.2.0
API ergonomics release. Two improvements landed:
- Method renames — the two "non-default" builder methods now name themselves explicitly at the call site.
- Generics —
GraphBuilderandCompiledGraphcarry the concreteStatesubclass through at type-check time, socast(MyState, ...)is no longer needed oninvoke()returns or projection arguments.
No spec-behavior changes; conformance fixtures continue to pass. Targets openarmature-spec v0.1.1.
Breaking changes
```diff
-builder.add_subgraph("research", research_subgraph, projection=MyProjection())
+builder.add_subgraph_node("research", research_subgraph, projection=MyProjection())
-builder.add_conditional("classify", route_fn)
+builder.add_conditional_edge("classify", route_fn)
```
Rationale: align names with what they add. `add_subgraph_node` pairs with `add_node` as the non-default node variant; `add_conditional_edge` pairs with `add_edge` as the non-default edge variant.
What's new: generic state typing (PEP 695)
`GraphBuilder`, `CompiledGraph`, `Node`, `FunctionNode`, `ConditionalEdge`, `SubgraphNode`, and `ProjectionStrategy` are all parameterized on a `StateT`-bound TypeVar.
```python
graph: CompiledGraph[MyState] = (
GraphBuilder(MyState)
.add_node("step", my_node)
.add_edge("step", END)
.set_entry("step")
.compile()
)
final = await graph.invoke(MyState(topic="..."))
final is typed MyState — field access works without cast()
print(final.topic)
```
Custom projections type their signatures directly:
```python
class MyProjection:
def project_in(
self,
parent_state: MyParentState,
subgraph_state_cls: type[MyChildState],
) -> MyChildState:
return subgraph_state_cls(topic=parent_state.topic)
```
Protocol is structural — no inheritance required.
See also
- Demo projects: openarmature-examples — `01-linear-pipeline` (minimal graph) and `02-routing-and-subgraphs` (conditional routing + subgraph + custom projection)
- Merged: #2 (renames), #3 (generics)
v0.1.0
Initial graph engine implementation. Targets openarmature-spec v0.1.1.
Included
- Typed `State` schema (frozen, strict) with per-field reducers (`last_write_wins`, `append`, `merge`)
- Static and conditional edges; `END` sentinel
- Subgraphs via `add_subgraph` with pluggable `ProjectionStrategy` (default: `FieldNameMatching`)
- Compile-time structural validation: `NoDeclaredEntry`, `UnreachableNode`, `DanglingEdge`, `MultipleOutgoingEdges`, `ConflictingReducers`
- Runtime error categories: `NodeException`, `EdgeException`, `ReducerError`, `RoutingError`, `StateValidationError` (all but the last carry `recoverable_state`)
- Spec conformance fixtures 001–010 passing
Note
Tag backfilled after v0.2.0 for version-history symmetry with openarmature-spec. No one was consuming v0.1.0 at the time; see v0.2.0 for the first release intended for external pinning.