Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,10 @@ def on_chain_start(
if context_api.get_value(_SUPPRESS_INSTRUMENTATION_KEY):
return

# Check for existing Traceloop context first
existing_workflow_name = context_api.get_value("workflow_name")
existing_entity_path = context_api.get_value("entity_path")

workflow_name = ""
entity_path = ""

Expand All @@ -402,10 +406,13 @@ def on_chain_start(
)

if kind == TraceloopSpanKindValues.WORKFLOW:
workflow_name = name
# Respect existing Traceloop decorator context if present
workflow_name = existing_workflow_name or name
entity_path = existing_entity_path or ""
else:
workflow_name = self.get_workflow_name(parent_run_id)
entity_path = self.get_entity_path(parent_run_id)
# Build entity path combining Traceloop context with LangChain component
entity_path = self._build_hybrid_entity_path(parent_run_id, name)

span = self._create_task_span(
run_id,
Expand Down Expand Up @@ -724,6 +731,8 @@ def get_workflow_name(self, parent_run_id: str):
return parent_span.workflow_name

def get_entity_path(self, parent_run_id: str):
# Use original LangChain chaining logic (no Traceloop context check here)
# This method is now only used as fallback when no Traceloop context exists
parent_span = self.get_parent_span(parent_run_id)

if parent_span is None:
Expand All @@ -738,6 +747,26 @@ def get_entity_path(self, parent_run_id: str):
else:
return f"{parent_span.entity_path}.{parent_span.entity_name}"

def _build_hybrid_entity_path(self, parent_run_id: str, component_name: str) -> str:
"""
Build entity path by combining Traceloop context with LangChain component names.
This ensures we preserve Traceloop decorator hierarchy while still showing LangChain components.
"""
# Check if we have existing Traceloop context
existing_entity_path = context_api.get_value("entity_path")

if existing_entity_path is not None:
# We have Traceloop context - add LangChain component to it
if existing_entity_path == "":
# Root level - just use component name
return component_name
else:
# Add component to existing path
return f"{existing_entity_path}.{component_name}"

# No Traceloop context - use original LangChain chaining logic
return self.get_entity_path(parent_run_id)

def _handle_error(
self,
error: BaseException,
Expand Down
Loading