Skip to content

Commit 835b8e1

Browse files
Add fan-out / subgraph / detached parenting to Langfuse observer
Extends LangfuseObserver with synthetic dispatch observations matching the OTel observer's structure. Spec §8.3 mandates Span observations for subgraph wrappers, fan-out nodes, and per-instance fan-out spans; §8.5 covers detached-trace mode where a configured subgraph or fan-out gets its own Langfuse Trace and the parent's dispatch observation surfaces metadata.detached_child_trace_ids. _InvState gains six new fields: - subgraph_observations: synthetic dispatch Span observations keyed by namespace prefix (lives in main Trace for non-detached, or in the detached Trace for detached subgraphs) - fan_out_instance_observations: per-instance dispatch Span observations keyed by prefix + (str(fan_out_index),) - detached_traces: prefix -> detached trace_id mapping that switches descendant observations onto the detached Trace - fan_out_instance_root_prefixes: tracks detached fan-out instance prefixes for the close path - fan_out_parent_node_name: cache populated from fan_out_config on the fan-out node's started event, bridging the lookup for the per-instance attribution metadata - detached_child_trace_ids: side-cache accumulator for the link-ids array on dispatch observations spawning detached children (the Protocol doesn't expose a metadata read accessor) LangfuseObserver gains two constructor kwargs (detached_subgraphs, detached_fan_outs) mirroring the OTel observer's surface. _resolve_parent_observation_id rewritten with full precedence: per-instance fan-out dispatch > subgraph dispatch (walked longest- first) > leaf-node ancestor walk > Trace root. Same precedence applied to _resolve_llm_parent_observation_id so an LLM call from inside a subgraph/fan-out parents correctly. _trace_id_for picks the right Trace (main or detached) for an observation by walking ancestor prefixes longest-first against the detached_traces map. Per-instance detached fan-out Traces are keyed by prefix + (str(fan_out_index),) and checked first. _sync_subgraph_observations is the synthesis driver: opens any ancestor dispatch observation the leaf event needs, closes any whose subtree we've left. Called before opening the leaf so the parent resolver sees them. Detached fan-out instance roots are exempted from cursor-move close — they close with the fan-out node's own completed event. Asymmetry documented in the helper docstrings: detached subgraphs synthesize a second "link" observation in the main Trace (subgraphs have no per-subgraph node event of their own, so there's no pre-existing observation to attach the link metadata to). Detached fan-out instances accumulate the link metadata on the fan-out node's pre-existing leaf observation instead. Four new unit tests cover the synthesis paths (no Langfuse spec fixtures exist for these in v0.23.0; spec considering a follow-on proposal to add them before v0.10.0 release): - subgraph dispatch parents inner-node observations - non-detached fan-out per-instance dispatches parent worker nodes - detached subgraph splits into two Traces with the metadata link - detached fan-out per-instance Traces with accumulating detached_child_trace_ids array on the fan-out node All 3 existing conformance fixtures (022-024) still pass; no regression on linear/LLM/prompt cases.
1 parent 885fee5 commit 835b8e1

2 files changed

Lines changed: 676 additions & 24 deletions

File tree

0 commit comments

Comments
 (0)