def _dfs_collect_inputs_from_events(
    kwarg_group: Tuple[str],
    kwarg_to_selector: Dict[str, Selector],
    span_id_to_child_events: Dict[str, List[pd.Series]],
    curr_event: pd.Series,
    ret: Dict[
        Tuple[str, Optional[str]],
        Dict[Tuple[str], List[Dict[str, FeedbackFunctionInput]]],
    ],
) -> None:
    """DFS collect inputs from events.

    Args:
        kwarg_group:
            List of kwargs that describe the same spans in their selector.
        kwarg_to_selector: Mapping from function kwargs to span selectors.
        span_id_to_child_events: Mapping from span id to child events.
        curr_event: Current event to process.
        ret:
            Mapping from (record_id, span_group) to kwarg group to inputs. This
            is what will be updated throughout the DFS.
    """
    # Convenience variables.
    record_attributes = curr_event["record_attributes"]
    record_id = record_attributes[SpanAttributes.RECORD_ID]
    selector = kwarg_to_selector[kwarg_group[0]]
    span_id = curr_event["trace"]["span_id"]
    span_name = curr_event["record"]["name"]
    # Handle span groups.
    span_groups = record_attributes.get(SpanAttributes.SPAN_GROUPS, [None])
    if isinstance(span_groups, str):
        span_groups = [span_groups]
    elif span_groups is None:
        span_groups = [None]
    # Check if row satisfies selector conditions.
    matched = False
    if selector.matches_span(span_name, record_attributes):
        # Collect inputs for this kwarg group.
        kwarg_group_inputs = {
            kwarg: kwarg_to_selector[kwarg].process_span(
                span_id, record_attributes
            )
            for kwarg in kwarg_group
        }
        # Place the inputs for this record id and every span group.
        for span_group in span_groups:
            ret[(record_id, span_group)][kwarg_group].append(kwarg_group_inputs)
        matched = True
    # Recurse on child events if necessary.
    if not matched or not selector.match_only_if_no_ancestor_matched:
        for child_event in span_id_to_child_events[span_id]:
            _dfs_collect_inputs_from_events(
                kwarg_group,
                kwarg_to_selector,
                span_id_to_child_events,
                child_event,
                ret,
            )
DFS collect inputs from events.

    Args:
        kwarg_group:
            List of kwargs that describe the same spans in their selector.
        kwarg_to_selector: Mapping from function kwargs to span selectors.
        span_id_to_child_events: Mapping from span id to child events.
        curr_event: Current event to process.
        ret:
            Mapping from (record_id, span_group) to kwarg group to inputs. This
            is what will be updated throughout the DFS.
    
src/feedback/trulens/feedback/computer.py