Skip to content

Commit f1e3ab2

Browse files
Bump spec pin to v0.17.1 for proposal 0019
Proposal 0019 reframes llm-provider §8 as a catalog of wire-format mappings, with the existing OpenAI-compatible body nested under §8.1. Purely textual on the spec side, no behavioral change, no new fixtures. Refresh code and doc references to §8.X to match the new structure: §8.1 → §8.1.1, §8.2 → §8.1.2, §8.3 → §8.1.3, §8.5.1 → §8.1.5.1, §8.1.1 → §8.1.1.1.
1 parent f1776ce commit f1e3ab2

9 files changed

Lines changed: 24 additions & 18 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ All notable changes to `openarmature-python` are documented in this file.
44

55
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).
66

7+
## [Unreleased]
8+
9+
### Notes
10+
11+
- **Pinned spec version bumped to v0.17.1.** Proposal 0019 (multi-provider wire-format extension) reframes llm-provider §8 as a catalog of wire-format mappings, with the existing OpenAI-compatible body nested under §8.1. Purely textual on the spec side — no behavioral change, no fixture changes. Code and doc references to §8.X updated to match the new structure (§8.1 → §8.1.1, §8.2 → §8.1.2, §8.3 → §8.1.3, §8.5.1 → §8.1.5.1, §8.1.1 → §8.1.1.1). All existing conformance fixtures continue to pass.
12+
713
## [0.8.0] — 2026-05-23
814

915
LLM-provider span payload and GenAI semconv release. Pinned spec

openarmature-spec

Submodule openarmature-spec updated 27 files

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Repository = "https://github.com/LunarCommand/openarmature-python"
4848
Specification = "https://github.com/LunarCommand/openarmature-spec"
4949

5050
[tool.openarmature]
51-
spec_version = "0.17.0"
51+
spec_version = "0.17.1"
5252

5353
[dependency-groups]
5454
dev = [

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

33
__version__ = "0.8.0"
4-
__spec_version__ = "0.17.0"
4+
__spec_version__ = "0.17.1"

src/openarmature/llm/providers/openai.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# Spec: realizes llm-provider §8 (concrete OpenAI provider) including
2-
# the §8.3 wire-error mapping table.
1+
# Spec: realizes llm-provider §8.1 (OpenAI-compatible wire-format mapping) including
2+
# the §8.1.3 wire-error mapping table.
33

44
"""OpenAI-compatible HTTPX-based provider.
55
@@ -389,7 +389,7 @@ async def _do_complete(
389389
return self._parse_response(cast("dict[str, Any]", payload_raw), schema_dict, schema_class)
390390

391391
# ------------------------------------------------------------------
392-
# Request building (spec §8.1)
392+
# Request building (spec §8.1.1)
393393
# ------------------------------------------------------------------
394394

395395
def _build_request_body(
@@ -433,7 +433,7 @@ def _build_request_body(
433433
},
434434
}
435435
elif not include_response_format:
436-
# On the fallback path the §8.5.1 contract is "response_format
436+
# On the fallback path the §8.1.5.1 contract is "response_format
437437
# MUST NOT be on the wire." RuntimeConfig is extra="allow" so
438438
# a caller could pass response_format through via the extras
439439
# loop above; strip it here so the fallback contract holds
@@ -442,7 +442,7 @@ def _build_request_body(
442442
return body
443443

444444
# ------------------------------------------------------------------
445-
# Response parsing (spec §8.2)
445+
# Response parsing (spec §8.1.2)
446446
# ------------------------------------------------------------------
447447

448448
def _parse_response(
@@ -460,7 +460,7 @@ def _parse_response(
460460
raise ProviderInvalidResponse(f"response missing required fields: {exc}") from exc
461461
finish_reason: str = finish_reason_raw if isinstance(finish_reason_raw, str) else "error"
462462

463-
# Per §8.2 (and conformance fixture 005's
463+
# Per §8.1.2 (and conformance fixture 005's
464464
# `function_call_legacy_finish_reason_mapping` case): the
465465
# legacy `finish_reason: "function_call"` value MUST be
466466
# normalized to the spec's `"tool_calls"`. This is a
@@ -717,13 +717,13 @@ def _augment_messages_with_schema_directive(
717717

718718

719719
def _message_to_wire(msg: Message) -> dict[str, Any]:
720-
"""Spec §8.1 request mapping for one message."""
720+
"""Spec §8.1.1 request mapping for one message."""
721721
if isinstance(msg, SystemMessage):
722722
return {"role": "system", "content": msg.content}
723723
if isinstance(msg, UserMessage):
724-
# Dual-shape user content (§8.1): string maps directly; a
724+
# Dual-shape user content (§8.1.1): string maps directly; a
725725
# content-block sequence maps to OpenAI's content-array form
726-
# per §8.1.1.
726+
# per §8.1.1.1.
727727
if isinstance(msg.content, str):
728728
return {"role": "user", "content": msg.content}
729729
return {
@@ -760,7 +760,7 @@ def _message_to_wire(msg: Message) -> dict[str, Any]:
760760
}
761761

762762

763-
# Spec §8.1.1: content-block to OpenAI content-array entry mapping.
763+
# Spec §8.1.1.1: content-block to OpenAI content-array entry mapping.
764764
# Both URL-referenced and inline-base64 image blocks go through
765765
# OpenAI's `image_url` entry shape; the inline case is expressed as
766766
# an RFC 2397 data: URI carrying media_type + base64_data. The
@@ -872,7 +872,7 @@ def classify_http_error(resp: httpx.Response) -> LlmProviderError:
872872
if status in (401, 403):
873873
return ProviderAuthentication(message or f"HTTP {status}")
874874
if status == 400:
875-
# Spec §8.3: HTTP 400 bodies that indicate the bound model
875+
# Spec §8.1.3: HTTP 400 bodies that indicate the bound model
876876
# rejected a content block map to provider_unsupported_content_block
877877
# rather than the generic provider_invalid_request. The
878878
# detection rule is implementation-defined.

tests/conformance/harness/directives.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ class MockResponse(_AllowExtras):
484484
Permissive shape because the body's content mirrors OpenAI's wire
485485
format which is wide and evolving; modelling every field would
486486
duplicate the OpenAI schema. The ``llm-provider`` capability's
487-
spec.md §8 is the authoritative shape.
487+
spec.md §8.1 is the authoritative shape.
488488
"""
489489

490490
status: int | None = None

tests/conformance/test_llm_provider.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
behavior in terms of OpenAI Chat Completions wire-format mock
55
responses + expected ``Provider.complete()`` / ``Provider.ready()``
66
outcomes. The harness drives the real :class:`OpenAIProvider` via
7-
``httpx.MockTransport`` so the wire-mapping path (spec §8) is
7+
``httpx.MockTransport`` so the wire-mapping path (spec §8.1) is
88
exercised end-to-end — fixture 005 explicitly tests that mapping, so
99
mocking at the Provider boundary would skip what we want to verify.
1010

tests/test_smoke.py

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

1010
def test_package_versions() -> None:
1111
assert openarmature.__version__ == "0.8.0"
12-
assert openarmature.__spec_version__ == "0.17.0"
12+
assert openarmature.__spec_version__ == "0.17.1"
1313

1414

1515
def test_spec_version_matches_pyproject() -> None:

tests/unit/test_llm_provider.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ def test_transient_categories_excludes_terminal_categories() -> None:
273273

274274

275275
# ---------------------------------------------------------------------------
276-
# classify_http_error — wire-mapping table (spec §8.3)
276+
# classify_http_error — wire-mapping table (spec §8.1.3)
277277
# ---------------------------------------------------------------------------
278278

279279

0 commit comments

Comments
 (0)