Skip to content

Commit 94b51ea

Browse files
release: prep 0.5.0rc1 (#28)
First real PyPI release after the 6-phase spec catch-up (v0.5.x → v0.10.0). Lands the version pin bump and the new CHANGELOG so the release pipeline (TestPyPI on rc tags, real PyPI on clean v0.5.0 tag) has a curated changelog and a matching version field to verify against. Per docs/RELEASING.md the release date in the CHANGELOG ``[0.5.0]`` heading stays as ``UNRELEASED`` until the ``release: 0.5.0`` PR drops the rc suffix and we tag.
1 parent c5761bb commit 94b51ea

6 files changed

Lines changed: 46 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Changelog
2+
3+
All notable changes to `openarmature-python` are documented in this file.
4+
5+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). The package follows [Semantic Versioning](https://semver.org/); pre-1.0 minor bumps may carry behavioral changes per [spec governance](https://github.com/LunarCommand/openarmature-spec/blob/main/GOVERNANCE.md).
6+
7+
## [Unreleased]
8+
9+
## [0.5.0] — UNRELEASED
10+
11+
First release on real PyPI. Catches the implementation up from spec v0.5.x to v0.10.0 across six phases — the spec accepted eight proposals while the python lib was at v0.3.1, and v0.5.0 lands all of them in one curated drop.
12+
13+
### Added
14+
15+
- **Typed conformance harness (Phase 0).** Single parametrised test target driving all 68 spec fixtures under discriminated-union YAML parsers. Replaces the earlier hand-rolled per-fixture wiring.
16+
- **Observer pair model (Phase 1, spec v0.6.0 / proposal 0005 §6).** `Observer` Protocol (async callable), `SubscribedObserver` with phase subscription set (`{"started", "completed", "checkpoint_saved"}`), `RemoveHandle.remove()`, and a serial delivery queue per spec §6 ordering. Observer exceptions don't propagate; reported via `warnings.warn`.
17+
- **Middleware (Phase 2, proposal 0004).** `Middleware` Protocol with the canonical `(state, next) → partial_update` shape, `compose_chain` runtime, and five stdlib middlewares: `RetryMiddleware`, `TimingMiddleware`, `ErrorRecoveryMiddleware`, `ShortCircuitMiddleware`, `TraceRecorderMiddleware`. Per-graph and per-node middleware composition.
18+
- **Fan-out runtime (Phase 3, proposal 0005 pipeline-utilities side).** `FanOutNode` for parallel fan-out over an `items_field` or a `count` (int or callable resolver). Configurable concurrency, error policy (`fail_fast` / `collect`), `inputs` / `extra_outputs` projection, optional `errors_field` collection. Composes with retry middleware on the fan-out node and on per-instance subgraphs.
19+
- **LLM provider (Phase 4, proposal 0006).** New `openarmature.llm` package: `Provider` Protocol with `ready()` / `complete(messages, tools=None, config=None)`; `OpenAIProvider` (HTTPX-based, OpenAI-compatible wire); typed `Message` / `ToolCall` / `Tool` / `Response` / `RuntimeConfig`; seven error categories (`ProviderAuthentication`, `ProviderUnavailable`, `ProviderInvalidRequest`, `ProviderInvalidResponse`, `ProviderInvalidModel`, `ProviderModelNotLoaded`, `ProviderRateLimit` with `retry_after`). Tool-call ids preserved verbatim through the wire.
20+
- **Checkpointing (Phase 5, proposal 0008).** `Checkpointer` Protocol (`save` / `load` / `list` / `delete`) with `CheckpointRecord` and `NodePosition` shapes; `InMemoryCheckpointer` reference impl; `CheckpointNotFound` / `CheckpointRecordInvalid` / `CheckpointSaveFailed` error categories; `checkpoint_saved` observer phase; resume-from-checkpoint semantics for fan-out and subgraph compositions.
21+
- **Observability / OTel (Phase 6, proposal 0007).** `OTelObserver` mapping observer events → OpenTelemetry spans with private `TracerProvider` (no global pollution); §4.4 detached subgraph + detached fan-out trace mode; §5.5 LLM-provider span emission with `disable_llm_spans` opt-out; §5.6 cross-cutting `openarmature.correlation_id` on every span; §10.8 `checkpoint_saved` zero-duration span. `install_log_bridge` wires the stdlib root logger through OTel's Logs Bridge (deprecation-aware via `opentelemetry-instrumentation-logging`) so log records emitted within an invocation carry the active span's `trace_id`/`span_id` plus `openarmature.correlation_id`. `prepare_sync` synchronous observer hook so logs emitted on the FIRST line of a node body (before any `await`) pick up the right span. Fan-out per-instance dispatch span synthesis (§5.4) with `parent_node_name` cached and applied per-instance.
22+
- **`current_correlation_id()` public API.** Read the per-invocation cross-backend join key from anywhere within the invocation's async call tree.
23+
- **Subgraph configuration plural form.** Builder accepts `subgraphs:` alongside `subgraph:` for fixture compatibility.
24+
25+
### Changed
26+
27+
- **Pinned spec version: 0.5.x → 0.10.0.** Lands proposals 0004 (middleware), 0005 (fan-out + observer pair model), 0006 (llm-provider), 0007 (observability/OTel), 0008 (checkpointing), 0011 (`prepare_sync` hook), 0012 (`completed` event after edge eval), 0013 (`fan_out_config` on `NodeEvent`).
28+
- **Edge-resolution failures share the preceding node's event pair (spec v0.9.0 / proposal 0012).** `routing_error` and `edge_exception` populate `error` on the preceding node's `completed` event with `post_state=None` instead of producing a separate pair. All five §4 runtime error categories now land via the same uniform mechanism.
29+
- **Observer protocol contract.** Async-only callable; phase-filtered delivery via `SubscribedObserver.phases`; serial single-task delivery worker; observer errors isolated via `warnings.warn`.
30+
31+
### Fixed
32+
33+
- **Log bridge filter placement.** Phase 6.0's `_CorrelationIdFilter` lived on the root logger; Python's logging propagation walks ancestor handlers but **not** ancestor filters, so child-logger records (the normal `logging.getLogger("module")` pattern) were missed. Replaced with a process-global `LogRecord` factory that fires uniformly at record construction.
34+
- **OTelObserver concurrency-safe state scoping.** Per-invocation span state now keyed by `invocation_id` so concurrent invocations sharing one observer instance don't collide on the in-flight span maps.
35+
- **Spec submodule pin sync.** Internal `spec_version` matched the submodule HEAD across phase boundaries; tracked via `tests/test_smoke.py`.
36+
37+
### Notes
38+
39+
- **First real PyPI publish.** Pre-release verification continues to flow through TestPyPI per `docs/RELEASING.md`. The `pypi` GitHub Environment requires a manual approval click before any real-PyPI upload — keep it on.
40+
- **Pre-1.0 SemVer.** Behavioral changes may land in MINOR bumps. Several Phase 1+ contracts changed shape vs. v0.4.0 — most user-visible: the observer pair model in Phase 1, the edge-resolution failure mechanism in Phase 6.1.
41+
- **Cross-language posture.** This release tracks spec v0.10.0; the OpenArmature TypeScript implementation will land separately under the same spec.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Python reference implementation of [OpenArmature](https://github.com/LunarCommand/openarmature-spec) — a workflow framework for LLM pipelines and tool-calling agents.
44

5-
**Status:** alpha. Implemented against spec v0.8.2.
5+
**Status:** alpha. Implemented against spec v0.10.0.
66

77
## Install
88

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "openarmature"
7-
version = "0.4.0rc0"
7+
version = "0.5.0rc1"
88
description = "Workflow framework for LLM pipelines and tool-calling agents."
99
readme = "README.md"
1010
requires-python = ">=3.12"

src/openarmature/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
"""OpenArmature — workflow framework for LLM pipelines and tool-calling agents."""
22

3-
__version__ = "0.4.0rc0"
3+
__version__ = "0.5.0rc1"
44
__spec_version__ = "0.10.0"

tests/test_smoke.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33

44
def test_package_versions() -> None:
5-
assert openarmature.__version__ == "0.4.0rc0"
5+
assert openarmature.__version__ == "0.5.0rc1"
66
assert openarmature.__spec_version__ == "0.10.0"

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)