def make_previous_layer_resid_post_mlp_scalar_deriver(
    dst_config: DstConfig,
) -> ScalarDeriver:
    """Several DSTs require use of the residual stream activations immediately preceding some particular set of activations.
    If the activations are MLP activations, this is simple: just the resid.post_attn activations in the same layer. If the
    activations are attention activations, this is a bit more complicated: resid.post_mlp in the previous layer if layer_index > 0,
    or resid.post_emb (which has no layers) if layer_index == 0.
    As a result, this gives the residual stream activations just prior to attention with layer_index k at entry k of
    activations_by_layer_index.
    This ScalarDeriver is for the latter case."""

    def get_scalar_sources(pass_type: PassType) -> tuple[RawScalarSource, RawScalarSource]:
        return (
            RawScalarSource(
                activation_location_type=ActivationLocationType.RESID_POST_MLP,
                pass_type=pass_type,
                layer_indexer=OffsetLayerIndexer(-1),
            ),  # resid.post_mlp
            RawScalarSource(
                activation_location_type=ActivationLocationType.RESID_POST_EMBEDDING,
                pass_type=pass_type,
                layer_indexer=NoLayersLayerIndexer(),
            ),  # resid.post_emb
        )

    if dst_config.derive_gradients:
        sub_scalar_sources: tuple[RawScalarSource, ...] = get_scalar_sources(
            PassType.FORWARD
        ) + get_scalar_sources(PassType.BACKWARD)
    else:
        sub_scalar_sources = get_scalar_sources(PassType.FORWARD)

    def tensor_calculate_derived_scalar_fn(
        raw_activation_data_tuple: tuple[torch.Tensor, ...],
        layer_index: LayerIndex,
        pass_type: PassType,
    ) -> torch.Tensor:
        if len(raw_activation_data_tuple) == 2:
            assert pass_type == PassType.FORWARD
            resid_post_mlp, resid_post_emb = raw_activation_data_tuple
        else:
            assert len(raw_activation_data_tuple) == 4
            _, _, resid_post_mlp, resid_post_emb = raw_activation_data_tuple
        assert layer_index is not None
        if layer_index == 0:
            return resid_post_emb
        else:
            assert layer_index > 0
            return resid_post_mlp

    return ScalarDeriver(
        dst=DerivedScalarType.PREVIOUS_LAYER_RESID_POST_MLP,
        dst_config=dst_config,
        sub_scalar_sources=sub_scalar_sources,
        tensor_calculate_derived_scalar_fn=tensor_calculate_derived_scalar_fn,
    )
Several DSTs require use of the residual stream activations immediately preceding some particular set of activations.
    If the activations are MLP activations, this is simple: just the resid.post_attn activations in the same layer. If the
    activations are attention activations, this is a bit more complicated: resid.post_mlp in the previous layer if layer_index > 0,
    or resid.post_emb (which has no layers) if layer_index == 0.
    As a result, this gives the residual stream activations just prior to attention with layer_index k at entry k of
    activations_by_layer_index.
    This ScalarDeriver is for the latter case.
neuron_explainer/activations/derived_scalars/residual.py