anthropics / anthropics/anthropic-sdk-python

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

Aberta
#1,647 2 comentários 0 reações 0 responsáveis Ver no GitHub
Linguagem predominante
Python
Estrelas
3.9k
Forks
853
Merge médio
1d 18h
PRs com merge (30d)
11

Descrição

### 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"]`.

Guia de contribuição

Abrir o guia de contribuição

Avaliação

Esta issue ainda não foi avaliada.

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.