Repository navigation
Conversation
…pletion Keep chain, agent and tool spans alive through sync and async generator exhaustion, errors, cancellation and explicit early close. Preserve send/throw protocols without buffering stream contents or leaving a current span in the consumer. Add real SDK lifecycle and localhost OTLP privacy regressions. Co-Authored-By: Claude Code <[email protected]>
Keep suppression, nested spans and context-variable tokens in one generator-owned context across sync and async advances and closes. Preserve Python 3.13 close return values and exercise exporter timeout behavior without private OTel fields. Co-Authored-By: Claude Code <[email protected]>
Initialize the wrapped native generator without registering a competing loop finalizer, restoring thread-local hooks before application code or awaits. The tracing wrapper now awaits cleanup in the generator-owned context before ending its span. Cover loop shutdown, explicit shutdown_asyncgens, garbage collection, awaited private cleanup, real cleanup failures, and unrelated generator hooks for chain, agent, and tool. E2B package matrix: 825 passed on Python 3.13 / OTel 1.45.2; 822 passed on Python 3.10 / OTel 1.29.0. Co-Authored-By: Claude Code <[email protected]>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Keep
fi-instrumentation-otelas the custom-application tracing core. Fix existingFITracer.chain,agent, andtooldecorators rather than adding a package or replacing their public APIs.send/throw/closeandasend/athrow/aclose, including cleanup errors, without swallowing application exceptions.FiSpan, preserving existing error privacy on the OTLP wire. Explicit early close is not an error.Ordinary functions/coroutines, decorator signatures, bound methods, tool metadata, and manual span contexts remain unchanged. No version bump, changelog edit, new dependency, or additional LLM decorator.
Why
On the development base, decorating a generator exported a completed span before its body ran. Iteration had no recording parent, and errors raised after yielding left the exported span UNSET. Generator-aware dispatch follows the design used by Braintrust; implementation is original.
Verification
All current verification below ran in fresh E2B cloud sandboxes with local mock collectors / in-memory OpenTelemetry exporters and no provider credentials. Core selection matches CI:
tests --ignore-glob='tests/test_framework_*.py'.q1104-pr344-refix-r2-red-01reproduced the double-close exception on all three decorators on both Python 3.13.18 / OTel 1.45.2 and Python 3.10.22 / OTel 1.29.0. The new regression suite failed 15 tests and passed 9 on each matrix entry; undecorated close-race controls passed.q1104-pr344-refix-r2-green-02passed the complete core suite: 825 passed, 6 skipped on Python 3.13.18 / OTel 1.45.2; 822 passed, 9 skipped on Python 3.10.22 / OTel 1.29.0. No framework package tests are claimed by this core-only run.q1104-pr344-refix-r2-reviewed-03re-ran the original review's close-race and instrumented-suppression probes, its independent SDK tests, and the new shutdown tests: 45 passed on each matrix entry. Three undecorated suppression-context probes were not selected; undecorated close-race controls were included.python/tests/test_async_generator_shutdown.pycovers all three decorators underasyncio.run, explicitshutdown_asyncgens, and garbage collection. It asserts no loop exception or false ERROR on successful awaited cleanup, span lifetime through the last cleanup await, generator-owned context tokens and suppression, real cleanup error propagation, and restoration of async-generator hooks for nested/unrelated generators. Existing real-SDK generator/context-isolation suites also pass, including localhost HTTP/protobuf OTLP privacy tests.Re-run with
python -m pytest python/tests/test_async_generator_shutdown.py python/tests/test_generator_decorators.py python/tests/test_generator_context_isolation.py -q.Stream ownership and rollout
Call
close()/aclose()when stopping early; usecontextlib.closing/aclosingaround consumers that may break or be cancelled between yields. A still-referenced, partially consumed generator remains open by design. Event-loop shutdown closes the tracing wrapper, which is the sole finalization owner of the wrapped generator. It awaits underlying cleanup in the generator-owned execution context before ending the span; the underlying generator is not separately registered for concurrent loop finalization.This fixes generator functions, not arbitrary functions/coroutines returning iterators. Use a manual span around consumption for those. No chunks are buffered, so no unbounded tracing memory growth.
Release the existing shared core through release-please after review. Customer docs describing this behavior are held until that package is on the registry. No packages should be deleted for this finding. No merge, tag, or registry publish was performed by this change.
E2E coverage
Not applicable (no product
e2e/harness in this SDK repository). Real-SDK and localhost OTLP tests cover the changed tracing contract. No database, API route, frontend, migration, or enterprise boundary changes.🤖 Generated with Claude Code