feat(tracing): derive LLM Ops URL source param from span Source field#1783
feat(tracing): derive LLM Ops URL source param from span Source field#1783saksharthakkar wants to merge 3 commits into
Conversation
The ?source= query param is what the server persists as Trace.Source (the span-body Source is ignored on ingest), but _build_url hardcoded CodedAgents, mislabeling every non-coded-agent producer that exports through this SDK (e.g. Agent Builder, which sets uipath.source=1=Agents). Derive source from span_list[0]['Source'] (SpanSource), defaulting to CodedAgents. Re-implements the intent of stale PR #1428 on the v3 URL. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0137aKdrnRYUdFg7iY7GmPYM
Guards the full attribute->Source->URL path so a future change to the uipath.source mapping can't silently regress source attribution. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0137aKdrnRYUdFg7iY7GmPYM
Release the LLM Ops trace source-derivation fix in _build_url. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0137aKdrnRYUdFg7iY7GmPYM
|
There was a problem hiding this comment.
Pull request overview
Updates the LLM Ops HTTP exporter to derive the source query parameter from the span’s resolved Source field (a SpanSource) instead of hardcoding CodedAgents, ensuring traces are attributed to the correct producing product on the server-side Trace.Source.
Changes:
- Derive
&source=...inLlmOpsHttpExporter._build_url()fromspan_list[0].get("Source"), defaulting toSpanSource.CODED_AGENTSwhen absent. - Add targeted unit + end-to-end-style tests validating explicit Sources and the
uipath.source=1 -> Source=Agents -> &source=Agentsflow. - Bump
uipathpackage version from2.12.4to2.12.5.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| packages/uipath/src/uipath/tracing/_otel_exporters.py | Builds v3 ingest URL using the span’s SpanSource for the source query param (with CodedAgents fallback). |
| packages/uipath/tests/tracing/test_otel_exporters.py | Adds regression and end-to-end guard tests for correct source= derivation and defaulting behavior. |
| packages/uipath/pyproject.toml | Version bump to release the tracing attribution fix. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
🚨 Heads up:
|



Motivation
The
?source=query param on the v3 ingest call is what the server persists asTrace.Source(the span bodySourceis ignored on ingest), but_build_urlhardcodedCodedAgents— so every non-coded-agent producer that exports through this SDK (e.g. Agent Builder, which setsuipath.source=1→Agents) was mislabeledCodedAgents, corrupting per-product migration/cost attribution on the v2→v3 dashboards. This derives the param from the span's already-resolvedSpanSource, so each producer self-labels with no per-repo changes. Supersedes stale PR #1428 (re-implemented cleanly on the current v3 URL +SpanSourceStrEnum).Summary
LlmOpsHttpExporter._build_urlnow readsspan_list[0]["Source"](aSpanSource) and renders its wire string into&source=…, defaulting toCodedAgentswhen absent (back-compat for coded agents and minimal/fallback span dicts).SpanSourcealongsideSpanStatusfromuipath.platform.common._span_utils./api/Traces/v3/spans) unchanged; no server, dependency, oruipath-agents-pythonchanges.Agents, explicitCodedAgents, missing-Sourcedefault, and an end-to-end guard drivinguipath.source=1throughotel_span_to_uipath_span().to_dict()→_build_url→&source=Agents.Tests performed
cd packages/uipath && uv run pytest tests/tracing/test_otel_exporters.py(documented via showboat):test_build_url_uses_span_source_agents(renderssource=Agents, notCodedAgents— the regression guard),test_build_url_uses_span_source_coded_agents,test_build_url_defaults_to_coded_agents_when_source_missing.test_agent_builder_span_yields_source_agents— real span withuipath.source=1resolves toSource=Agentsand yields&source=Agents._otel_exporters.pycoverage 73%.Successful, 4 spans ingested to/api/Traces/v3/spans(200). The trace's agent spans storedSource=Agents, and running the deployed branch's_build_urlagainst that trace emits…&source=Agents(vs&source=CodedAgentsfor a Source-less span).OR Test
Test plan
uv run pytest tests/tracing/test_otel_exporters.pygreen (35/35)_build_urlhas no hardcodedsource=literal; v3 endpoint intactruff check/ruff format --checkclean on changed filesuipath.source=1) exports assource=AgentsTrace.Source=Agentsfrom the query param (server-side behavior; out of scope for this diff)🤖 Generated with Claude Code
https://claude.ai/code/session_0137aKdrnRYUdFg7iY7GmPYM