| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
#485) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…r span (#484) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…ies (1:1) Previously _begin_obs skipped the obs wrapper for ANY Temporal activity (Option A) and only stamped the ambient RunActivity span, so all business spans in a turn collapsed onto ONE obs span (52:1). But inside a *business* activity, start_span and end_span run in the SAME process, so a wrapper is safe there. Option A is only required for the SDK's own dispatched START_SPAN/END_SPAN activities (the in_temporal_workflow path), where start and end are separate activities on possibly different workers. Discriminate on activity type: _in_tracing_dispatch_activity() is true only for the "start-span"/"end-span" activities. For everything else (sync, or a business activity) open a real per-step wrapper — it nests under the interceptor's ambient RunActivity span and closes in-process, giving each business span its own obs span (1:1), matching the sync path. The bounded _OBS_HANDLES registry backstops any mis-discrimination.
…P startup Replace the SDK's inline observability edge (#484/#485/#490/#491) with thin shims that delegate to the shared sgp-obs library: - obs_ids.py / obs_span.py / temporal.py / trace.py: delegate correlation, the per-step wrapper span, the begin-obs decision, and the Temporal interceptors to sgp_obs.traces backends + Correlator. - adk/pyproject.toml: add sgp-obs==0.2.0rc1; root pyproject: add the CodeArtifact `scale` index + explicit source for sgp-obs. Also wire sgp_obs.traces.init_tracing() into the BaseACPServer lifespan. Without it, get_tracer() resolves to the API-default ProxyTracerProvider: obs wrapper spans never record or export, so no span carrying the <source>.business_trace_id reverse anchor reaches the collector. init_tracing adopts an app-installed provider if present, else installs one with the OTLP exporter (fail-open). Validated end-to-end in sgp-dev (rocket-mock + audit): agent registers, 20/20 business spans correlate (obs ids in span metadata), per-step wrapper spans record with the reverse anchor, and force_flush to the collector succeeds. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ctly The obs_ids/obs_span modules were pure backward-compat adapters: they preserved the SDK's legacy surface (get_obs_mode/obs_correlation/open_obs_span/ close_obs_span/tag_ambient_obs_span/ObsSpanHandle + DD_ONLY/LGTM strings) by translating to/from sgp_obs's own types on every call. That adapter layer is the bulk of the delegation and buys nothing — trace.py is the only consumer. Delete both modules and have trace.py talk to sgp_obs directly: build the SpanRequest/BusinessRef, run the Correlator, map SGP_OBS_MODE -> ObsMode, and close via the sgp_obs handle (SpanError). Also removes the now-dead _in_tracing_dispatch_activity (the wrapper-vs-ambient decision lives entirely in the Correlator via is_dispatch_boundary). Tests: delete the shim-targeted suites (test_obs_ids/test_obs_span/ test_obs_span_fallback/test_temporal_obs_backend) — that behavior is owned by sgp_obs's own tests now. Keep the registry/error/interceptor tests (they cover trace.py's own logic); the registry test uses a minimal fake handle. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
_acp_dispatch_span was per-service boundary glue living in the SDK. The ACP->Temporal dispatch is a transport boundary, not service logic, so it now lives once in the library (sgp_obs.traces.dispatch_span). Replace the 45-line function + its sys/contextlib imports with two `with dispatch_span(...)` calls, passing the business id as an attribute (agentex.task_id) so the generic library stays source-agnostic. Bumps the sgp-obs pin to 0.3.0 (adds dispatch_span + the ALWAYS_ON sampler fix). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Now that init_tracing auto-instruments outbound httpx, the span-export calls get traced themselves and nest back into the trace being exported — PUT /v5/spans/batch (SGP) and POST /spans (Agentex), plus the egp auth/db subtree a propagated traceparent drags in. Wrap both processors' async exports in sgp_obs.traces.suppress_instrumentation so the export makes no span and injects no traceparent. Verified in sgp-dev: export-pollution spans went 51 -> 0 while each business step still shows its real work (e.g. run_agent_streamed -> the LLM call). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…on by default Every agentex agent makes outbound HTTP (LLM/egp), so httpx instrumentation is universal — pull the extra in the SDK so init_tracing's egress instrumentation (and the export suppression that pairs with it) actually functions without each agent opting in. DB instrumentation (sgp-obs[db]) stays per-agent opt-in. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wrap both completion_stream (sync) and acompletion_stream (async) with sgp_obs.traces.instrument_stream so every litellm streaming call emits one gen_ai.chat span with TTFT/TTAT events + the decode-window timing (tps, tpot, output tokens) — filling the "span for TTFT but nothing for the streaming" gap for non-Temporal / litellm agents. Provider extractors count content-bearing deltas; fail-open, chunks pass through unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wire SGPLLMGateway.{completion_stream,acompletion_stream} through
sgp_obs.traces.instrument_stream so scale-gp streaming gets the same gen_ai.chat
span (TTFT/TTAT + decode-window timing) as litellm. Both gateways yield the same
OpenAI-shaped Completion chunk, so the extractors + attribute builder move to a
shared _stream_obs module (litellm refactored to use it; scale-gp tags
gen_ai.system=scale-gp). Streaming instrumentation is now uniform across adapters.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
After init_tracing, register sgp_obs's openai-agents tracing bridge so a Runner turn's internal phases (generation/tool/handoff) show up in Tempo under the business step instead of a dark gap. Fail-open no-op for non-openai-agents agents. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Every agent's message/send and task/create handler is now wrapped with sgp-obs `business_trace(business_trace_id=lambda p: p.task.id)` at registration, so an agent gets the full business<->obs correlation edge — the turn anchor plus the process-local correlation context the openai-agents bridge and auto-egress read for their reverse tag — with NO per-agent code. Proven manually on analyst-agent (trace 9ad202d0b0bbdc0a78d8e5719c830811); this bakes it into the base server so no agent has to decorate. The decorator preserves the handler's shape (sync / async / async-generator), so streaming message/send handlers keep streaming. Fail-open + version-tolerant: `_with_business_trace` no-ops when the installed sgp-obs predates `business_trace` (defensive import, same stance as init_tracing), so this is inert until the sgp-obs pin is bumped to the release that ships it (0.5.0) — no code change needed here at that point. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…struction Pass the flag into the sgp_obs Correlator that _begin_obs builds for every adk business span, so the opt-out actually takes effect on the primary correlation path. Behavior lives in sgp_obs (scaleapi#158071); this is the construction pass-through. Version-resilient (_build_correlator): an installed sgp_obs that predates the `correlate_business` parameter raises TypeError on the kwarg, so we fall back to the no-arg form and correlation stays always-on rather than dying. The flag takes effect once the sgp-obs pin is bumped to the release that wired it (0.5.0). Confirmed against the currently-pinned 0.3.0: fallback, no crash. Test: env parsing + no-crash fallback + (when supported) the flag reaching the Correlator instance. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… on)
Match sgp_obs env_off: disable ONLY on an explicit {0,false,no,off}; unset,
empty, or an unrecognized value stays ON. Adds "off" to the token set and stops
treating an unrecognized value as True-by-coincidence — now it's True by rule
(opt-out), so a typo can't silently drop correlation. Test covers off-tokens +
empty/typo staying on.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| Back | FazBrowse Home | New Git URL |
What
Moves the SDK's inline observability edge (the correlation/wrapper-span/temporal-interceptor work from #484/#485/#490/#491) out into the shared sgp-obs library, so the SDK just delegates. Net diff vs main is the delegated implementation — the intermediate inline code (added in the #484/#485/#491 commits, which were never merged to main) is replaced by thin shims.
Why init_tracing matters
Without it, get_tracer() resolves to the API-default ProxyTracerProvider: obs wrapper spans never record or export. The forward edge (obs ids in business-span metadata) still fills from ambient/propagated W3C context, but no obs span carrying the <source>.business_trace_id reverse anchor ever reaches the collector, so the business→obs pivot has nothing to land on. init_tracing adopts an app-installed provider if present, else installs one with the OTLP exporter. Fail-open (never raises out of startup).
Validation (sgp-dev, rocket-mock + audit)
🤖 Generated with Claude Code
Greptile Summary
The PR delegates tracing correlation, wrapper spans, Temporal propagation, streaming instrumentation, and ACP tracing initialization to sgp-obs.
Confidence Score: 5/5
The PR appears safe to merge.
No blocking failure remains.
Important Files Changed
Sequence Diagram
Reviews (10): Last reviewed commit: "fix(tracing): align _correlate_business ..." | Re-trigger Greptile