You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Add FailureIsolationMiddleware (proposal 0050)
A third bundled middleware primitive alongside RetryMiddleware and
TimingMiddleware. It catches exceptions escaping a wrapped node and
returns a configured degraded partial update, so a non-critical node
can fail without aborting the whole invocation. On a catch it emits a
distinct FailureIsolatedEvent (with a CaughtException record) that the
bundled OTel and Langfuse observers render, keeping the degradation
visible in traces. A raising on_caught hook is isolated so a buggy
telemetry hook cannot defeat the recovery.
First of two PRs for proposal 0050; call-level retry follows. No
spec-pin change (0050 is already within the v0.53.0 pin).
* Clarify failure-isolation docs from PR review
Two doc-only changes from CoPilot review of PR #149, no behavior
change:
- The module docstring now states that degraded_update is resolved
once at catch time (which populates the event's post_state), with
the numbered steps covering only the observable order after that.
- A comment at the FailureIsolatedEvent dispatch documents that
attempt_index is the intentional node-level baseline (not a
per-attempt index) and that span parenting is unaffected.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,6 +6,10 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). The
6
6
7
7
## [Unreleased]
8
8
9
+
### Added
10
+
11
+
- **`FailureIsolationMiddleware`** (proposal 0050, pipeline-utilities §6.3). A third bundled middleware primitive alongside `RetryMiddleware` and `TimingMiddleware`. It catches exceptions escaping the wrapped node's inner chain and returns a configured degraded partial update, so a non-critical node can fail without aborting the whole invocation. Configuration: `degraded_update` (a static mapping or a `state -> partial_update` callable, resolved at catch time), `event_name` (required, no default, since a generic name makes downstream telemetry strictly worse), an optional `predicate` (`Exception -> bool`; only matching exceptions are caught, others propagate), and an optional async `on_caught` hook. It catches `Exception`; `BaseException` (cancellation) propagates, matching `RetryMiddleware`. On a catch it dispatches a new framework-emitted `FailureIsolatedEvent` (a distinct observer-event variant carrying `event_name`, the wrapped node's lineage identity, `pre_state` / `post_state`, and a `CaughtException` record of category plus message) onto the observer delivery queue; the bundled OTel and Langfuse observers render it as a marker span / observation. Compose it OUTER of `RetryMiddleware` for the "retry transients, degrade gracefully on exhaustion" pattern. Additive: existing pipelines see no behavior change, and the spec pin is unchanged (0050 is already within the v0.53.0 pin).
12
+
9
13
## [0.13.0] — 2026-06-09
10
14
11
15
LLM provider hardening release. The pinned spec advances from v0.46.0 to v0.53.0, absorbing four implemented proposals. Proposal 0049 introduces the first spec-normatively-typed observer event variant, `LlmCompletionEvent`, dispatched on every successful LLM provider call; proposal 0058 adds the failure-side counterpart, `LlmFailedEvent`; proposal 0057 extends the completion variant with eight request-side fields. The bundled `OpenAIProvider` retires its sentinel-namespace `NodeEvent` emission for LLM calls entirely, and the OTel and Langfuse observers now drive their LLM span / Generation from the typed events with back-dated timestamps so durations reflect the adapter boundary. Proposal 0047 closes implicit prefix-cache wire-byte stability: `Response.usage` gains cache-stat fields, the OTel observer emits `openarmature.llm.cache_read` attributes, and the OpenAI Chat Completions request body is byte-stable across equivalent inputs regardless of dict insertion order. Custom observers that filtered LLM calls by sentinel namespace MUST migrate to `isinstance` discrimination; `LLM_NAMESPACE` and `LlmEventPayload` remain as a documented compatibility surface.
0 commit comments