Skip to content

feat(tracing): add a run_id-keyed span provider to UiPathSpanUtils [PLT-112227] - #1941

Open
kshitij858 wants to merge 2 commits into
mainfrom
feat/run-span-provider
Open

kshitij858 wants to merge 2 commits into
mainfrom
feat/run-span-provider

Conversation

@kshitij858

@kshitij858 kshitij858 commented Oct 12, 2026 •

Copy link
Copy Markdown

Why

UiPathSpanUtils lets a framework register providers for the current span and its ancestors. Both take no arguments: they answer for whatever is running right now.

A LangChain callback handler only has the run_id of the call it is handling, and it needs the span the runtime opened for that call. The current span is the wrong question for two reasons: callbacks for concurrent calls interleave, and an end hook can run after the runtime has already moved on.

Today the only way to get that span is to read framework internals. uipath-governance-python does exactly that: it reads uipath_agents._observability.llmops.span_hierarchy.SpanHierarchyManager to parent its policy-check spans under the LLM or tool call they checked. This PR adds a public seam so that private read can go away.

What

  • UiPathSpanUtils.register_run_span_provider(Callable[[UUID], Optional[Span]] | None)
  • UiPathSpanUtils.get_run_span(run_id) -> Optional[Span]

These follow the existing providers' pattern: the provider is stored as a ClassVar, None unregisters it, and a provider that raises is logged at WARNING and returns None. No existing behaviour changes.

uipath-agents will register the provider, backed by SpanHierarchyManager, in a companion PR.

Version

uipath-core goes from 0.5.33 to 0.5.34.

Testing

  • Three tests in tests/tracing/test_external_integration.py: the lookup resolves through the provider, no provider returns None, and a raising provider returns None.
  • Locally: pytest tests/tracing, ruff check, ruff format --check, mypy src tests, and uv lock --check in all three packages all pass.

🤖 Generated with Claude Code

…LT-112227]

The existing current-span providers answer for whatever is executing
now. A caller holding a framework run id (e.g. a LangChain callback's
run_id) has no way to ask for the span that run opened, so consumers
read framework internals instead. Add register_run_span_provider /
get_run_span, mirroring the existing providers' fail-safe lookup.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added test:uipath-langchain Triggers tests in the uipath-langchain-python repository test:uipath-runtime test:uipath-integrations labels Oct 12, 2026
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@kshitij858
kshitij858 marked this pull request as ready for review October 12, 2026 18:31
Copilot AI balanced review requested due to automatic review settings October 12, 2026 18:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The public setter lacks its required return annotation, and the documented warning behavior is not asserted.

2 open findings
What changed in this PR

Adds run-ID-based span lookup to support concurrent external framework callbacks.

Changes:

  • Adds registration and lookup APIs for run-specific spans.
  • Adds provider behavior tests.
  • Bumps uipath-core to 0.5.34.
File Description
packages/​uipath-core/​src/​uipath/​core/​tracing/​span_utils.py Implements the run span provider.
packages/​uipath-core/​tests/​tracing/​test_external_integration.py Tests lookup and error handling.
packages/​uipath-core/​pyproject.toml Bumps package version.
packages/​uipath-core/​uv.lock Updates locked core version.
packages/​uipath-platform/​uv.lock Updates locked core version.
packages/​uipath/​uv.lock Updates locked core version.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +336 to +338
def register_run_span_provider(
run_span_provider: Optional[Callable[[UUID], Optional[Span]]],
):
Comment on lines +121 to +135
def test_run_span_provider_raises_exception():
"""Test that exceptions from the run span provider are caught."""
from uuid import UUID, uuid4

from uipath.core.tracing.span_utils import UiPathSpanUtils

def failing_provider(run_id: UUID):
raise RuntimeError("Provider failed!")

UiPathSpanUtils.register_run_span_provider(failing_provider)

assert UiPathSpanUtils.get_run_span(uuid4()) is None

# Clean up
UiPathSpanUtils.register_run_span_provider(None)
@github-actions

Copy link
Copy Markdown

🚨 Heads up: uipath-integrations cross-tests are FAILING 🚨

Your changes may break one or more integrations in uipath-integrations-python:

  • uipath-openai-agents
  • uipath-google-adk
  • uipath-agent-framework
  • uipath-llamaindex
  • uipath-pydantic-ai

⚠️ These checks are NOT enforced by branch protection rules. Please review the failures before merging.

🔍 Inspect the failed run →

@sonarqubecloud

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

🚨 Heads up: uipath-langchain cross-tests are FAILING 🚨

Your changes may break the uipath-langchain-python integration.

⚠️ These checks are NOT enforced by branch protection rules. Please review the failures before merging.

🔍 Inspect the failed run →

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test:uipath-integrations test:uipath-langchain Triggers tests in the uipath-langchain-python repository test:uipath-runtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants