Skip to content

fix(openai): handle Azure stream chunks without delta#1648

Merged
hassiebp merged 2 commits intomainfrom
codex/fix-azure-stream-delta-none
May 8, 2026
Merged

fix(openai): handle Azure stream chunks without delta#1648
hassiebp merged 2 commits intomainfrom
codex/fix-azure-stream-delta-none

Conversation

@hassiebp
Copy link
Copy Markdown
Contributor

@hassiebp hassiebp commented May 8, 2026

Summary

Fixes Azure OpenAI streaming traces when Azure emits a trailing content-filter chunk whose chat choice has delta=None.

The OpenAI stream extractor previously dereferenced delta.__dict__ unconditionally for OpenAI v1 responses. In Azure deployments with custom content filters, the trailing metadata-only chunk can have no delta, causing final stream extraction to fail internally. Because finalization catches extraction errors, the generation span ended without assistant output or usage details.

This PR:

  • treats delta=None as an empty delta while continuing to process prior streamed content
  • preserves the last non-null usage and finish_reason across trailing metadata-only chunks
  • adds a regression test with an Azure-style trailing content-filter chunk

Verification

  • uv run --frozen pytest tests/unit/test_openai.py -q
  • uv run --frozen ruff check langfuse/openai.py tests/unit/test_openai.py
  • uv run --frozen ruff format --check langfuse/openai.py tests/unit/test_openai.py
  • uv run --frozen mypy langfuse --no-error-summary

Disclaimer: Experimental PR review

Greptile Summary

Fixes a crash in Azure OpenAI streaming when Azure emits a trailing content-filter chunk with delta=None and finish_reason=None, which previously caused finalization to produce spans without output or usage data.

  • Adds a delta is not None guard before calling delta.__dict__ for OpenAI v1 objects, then falls back to an empty dict so downstream logic runs safely.
  • Changes usage and finish_reason accumulation to a "last non-null wins" pattern, preserving values from earlier normal chunks when a trailing metadata-only chunk clears them.
  • Adds a regression test with an Azure-style three-chunk stream (content chunk → stop chunk with usage → trailing content-filter chunk with delta=None).

Confidence Score: 5/5

Safe to merge — the fix is narrowly scoped to the stream extractor, does not alter any public API or data model, and is covered by a direct regression test.

The change is a minimal three-part defensive fix in one function, each part independently safe: a null guard on delta before dict conversion, an empty-dict fallback so the rest of the loop body runs unchanged, and a non-null-only assignment pattern for usage and finish_reason. The regression test exercises exactly the failing scenario end-to-end and checks all three affected outputs (content, finish_reason, usage).

No files require special attention.

Sequence Diagram

sequenceDiagram
    participant Azure as Azure OpenAI API
    participant Extractor as _extract_streamed_openai_response
    participant Span as Langfuse Span

    Azure->>Extractor: "chunk 1 — delta with content, finish_reason=None, usage=None"
    Note over Extractor: model set, content accumulated
    Azure->>Extractor: "chunk 2 — delta empty, finish_reason="stop", usage={tokens}"
    Note over Extractor: finish_reason preserved (non-null), usage preserved (non-null)
    Azure->>Extractor: "chunk 3 — delta=None, finish_reason=None, usage=None (content-filter)"
    Note over Extractor: delta=None → skip __dict__ → treat as {}<br/>finish_reason=None → keep "stop"<br/>usage=None → keep prior usage
    Extractor->>Span: "finalize with content, finish_reason="stop", usage={tokens}"
Loading

Reviews (1): Last reviewed commit: "fix(openai): handle Azure stream chunks ..." | Re-trigger Greptile

@hassiebp hassiebp marked this pull request as ready for review May 8, 2026 14:00
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

@claude review

@hassiebp hassiebp enabled auto-merge (squash) May 8, 2026 14:05
@hassiebp hassiebp merged commit fd5decd into main May 8, 2026
19 checks passed
@hassiebp hassiebp deleted the codex/fix-azure-stream-delta-none branch May 8, 2026 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant