Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Stream wrappers cannot finalize telemetry for generator-backed streams

Aperta
#386 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
48/100
Tipo di issue
Funzionalità
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
python
Ambito
observability

Direzione di ricerca

Inizia leggendo le implementazioni di SyncStreamWrapper e AsyncStreamWrapper in opentelemetry.util.genai.stream, quindi esamina l'utilizzo basato su generatori descritto per qwen-agent e il pacchetto qwenpaw proposto in #311. Il lavoro è completato quando gli stream basati su generatori finalizzano la telemetria quando il consumo si interrompe prematuramente, preservando al contempo la forma originale di async_generator e gestendo il comportamento di chiusura degli async generator.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

SyncStreamWrapper / AsyncStreamWrapper are wrapt proxies that finalize telemetry from close() / __exit__ / __aexit__ and from iteration reaching its end. When the wrapped stream is a generator and the caller stops consuming it early, none of those run: the caller drops the proxy, and GC finalizes the underlying generator directly, so the span is never ended.

This is normal traffic for agent instrumentations that wrap generator-returning APIs. For example QwenPaw's ACP server breaks out of the async for when the client cancels a turn:

async for msg, _is_last in runner.query_handler(msgs, request=request):
    if cancel_event.is_set():
        break

Effects: the invoke_agent span is never exported and never recorded in gen_ai.client.operation.duration, and because the invocation attached its context at start and only detaches on finalize, later spans in the same task become children of the span that never ended.

Two related gaps:

  • AsyncStreamWrapper expects the stream to expose async close(), but async generators expose aclose(). Instrumentations have to override aclose / close / __aexit__ to bridge that.
  • No proxy-based wrapper can catch GC teardown at all. Catching it requires the wrapper to itself be an async generator, so GeneratorExit reaches a finally:
async def _driver():
    try:
        async for item in gen:
            yield item
    finally:
        ...finalize telemetry...
        await gen.aclose()

This shape does finalize on the break path above, and it keeps the returned object an async_generator, which is closer to the SDK's original type than a proxy is.

Suggest a generator-aware wrapper in opentelemetry.util.genai.stream so instrumentations wrapping generator APIs (qwen-agent, the proposed qwenpaw package in #311) get correct finalization instead of each working around it.

Lingua principale
Python
Stelle
47
Fork
102
Merge medio
2g 13h
PR unite (30g)
111

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di open-telemetry/opentelemetry-python-genai

Tutte le issue di open-telemetry/opentelemetry-python-genai

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.