anthropics / anthropics/anthropic-sdk-python

Bedrock stream decoder drops SSE event types; type-less chunks construct as RawMessageStartEvent(message=None)

オープン
#1,647 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る
主要言語
Python
スター
3.9k
フォーク
853
平均マージ
1日 18時間
マージ済み PR(30日)
11

説明

### Summary

The Bedrock stream decoder (`anthropic/lib/bedrock/_stream_decoder.py`) hardcodes `ServerSentEvent(event="completion")` for every chunk, discarding the real event type. Downstream, the `"completion"` branch in `_streaming.py::__stream__` never backfills `data["type"]` (unlike the direct-SSE branch). Chunks without a `type` field — notably Bedrock's `amazon-bedrock-invocationMetrics` trailer — then hit non-validating `construct_type` against the stream-event union, which falls back to the **first union member** and yields `RawMessageStartEvent(message=None)` — an object that violates the SDK's own type contract (`message` is typed as non-optional).

### Reproduction (anthropic 0.105.2, offline)

```python
from anthropic._models import construct_type
from anthropic.types.beta import BetaRawMessageStreamEvent

event = construct_type(
value={"amazon-bedrock-invocationMetrics": {"inputTokenCount": 1}},
type_=BetaRawMessageStreamEvent,
)
print(type(event).__name__, event.message)
# BetaRawMessageStartEvent None
```

Any consumer that trusts the type annotations (e.g. `event.message.usage`) crashes with `AttributeError: 'NoneType' object has no attribute 'usage'`. We hit this in production via pydantic-ai's streaming path on `AsyncAnthropicBedrock` — intermittent 500s whenever a stream contained the invocationMetrics trailer.

### Expected

Either:
- the Bedrock decoder preserves/backfills the event type from the chunk payload's `type` field (the payloads do carry one for real events), and drops/ignores non-Messages chunks like `amazon-bedrock-invocationMetrics`, or
- stream-event construction validates and raises a clear error instead of silently producing a contract-violating first-union-member object.

### Notes

- Related but distinct from #1477 (decoder raises `ValueError` on error SSE events) — same file, different gap: this one is about *successful* streams containing type-less chunks.
- Direct (non-Bedrock) SSE is unaffected: that branch carries the event type and backfills `data["type"]`.

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。