async def feedback_action(
        # Default action arguments:
        events: Optional[List[Dict]] = None,
        context: Optional[Dict] = None,
        llm: Optional[BaseLanguageModel] = None,
        config: Optional[RailsConfig] = None,
        # Rest of arguments are specific to this action.
        function: Optional[str] = None,
        selectors: Optional[Dict[str, Union[str, serial_utils.Lens]]] = None,
        verbose: bool = False,
    ) -> ActionResult:
        """Run the specified feedback function from trulens.

        To use this action, it needs to be registered with your rails app and
        feedback functions themselves need to be registered with this function.
        The name under which this action is registered for rails is `feedback`.

        Usage:
            ```python
            rails: LLMRails = ... # your app
            language_match: Feedback = Feedback(...) # your feedback function

            # First we register some feedback functions with the custom action:
            FeedbackAction.register_feedback_functions(language_match)

            # Can also use kwargs expansion from dict like produced by rag_triad:
            # FeedbackAction.register_feedback_functions(**rag_triad(...))

            # Then the feedback method needs to be registered with the rails app:
            rails.register_action(FeedbackAction.feedback)
            ```

        Args:
            events: See [Action
                parameters](https://github.com/NVIDIA/NeMo-Guardrails/blob/develop/docs/user_guides/python-api.md#special-parameters).

            context: See [Action
                parameters](https://github.com/NVIDIA/NeMo-Guardrails/blob/develop/docs/user_guides/python-api.md#special-parameters).

            llm: See [Action
                parameters](https://github.com/NVIDIA/NeMo-Guardrails/blob/develop/docs/user_guides/python-api.md#special-parameters).

            config: See [Action
                parameters](https://github.com/NVIDIA/NeMo-Guardrails/blob/develop/docs/user_guides/python-api.md#special-parameters).

            function: Name of the feedback function to run.

            selectors: Selectors for the function. Can be provided either as
                strings to be parsed into lenses or lenses themselves.

            verbose: Print the values of the selectors before running feedback
                and print the result after running feedback.

        Returns:
            ActionResult: An action result containing the result of the feedback.

        Example:
            ```colang
            define subflow check language match
                $result = execute feedback(\\
                    function="language_match",\\
                    selectors={\\
                    "text1":"action.context.last_user_message",\\
                    "text2":"action.context.bot_message"\\
                    }\\
                )
                if $result < 0.8
                    bot inform language mismatch
                    stop
            ```
        """

        feedback_function = registered_feedback_functions.get(function)

        if feedback_function is None:
            raise ValueError(
                f"Invalid feedback function: {function}; "
                f"there is/are {len(registered_feedback_functions)} registered function(s):\n\t"
                + "\n\t".join(registered_feedback_functions.keys())
                + "\n"
            )

        fname = feedback_function.name

        if selectors is None:
            raise ValueError(
                f"Need selectors for feedback function: {fname} "
                f"with signature {inspect.signature(feedback_function.imp)}"
            )

        selectors = {
            argname: (
                serial_utils.Lens.of_string(arglens)
                if isinstance(arglens, str)
                else arglens
            )
            for argname, arglens in selectors.items()
        }

        feedback_function = feedback_function.on(**selectors)

        source_data = dict(
            action=dict(events=events, context=context, llm=llm, config=config)
        )

        if verbose:
            print(fname)
            for argname, lens in feedback_function.selectors.items():
                print(f"  {argname} = ", end=None)
                # use pretty print for the potentially big thing here:
                print(
                    text_utils.retab(
                        tab="    ", s=pformat(lens.get_sole_item(source_data))
                    )
                )

        context_updates = {}

        try:
            result = feedback_function.run(source_data=source_data)
            context_updates["result"] = result.result

            if verbose:
                print(f"  {fname} result = {result.result}")

        except Exception:
            context_updates["result"] = None

            return ActionResult(
                return_value=context_updates["result"],
                context_updates=context_updates,
            )

        return ActionResult(
            return_value=context_updates["result"],
            context_updates=context_updates,
        )
Run the specified feedback function from trulens.

        To use this action, it needs to be registered with your rails app and
        feedback functions themselves need to be registered with this function.
        The name under which this action is registered for rails is `feedback`.

        Usage:
            ```python
            rails: LLMRails = ... # your app
            language_match: Feedback = Feedback(...) # your feedback function

            # First we register some feedback functions with the custom action:
            FeedbackAction.register_feedback_functions(language_match)

            # Can also use kwargs expansion from dict like produced by rag_triad:
            # FeedbackAction.register_feedback_functions(**rag_triad(...))

            # Then the feedback method needs to be registered with the rails app:
            rails.register_action(FeedbackAction.feedback)
            ```

        Args:
            events: See [Action
                parameters](https://github.com/NVIDIA/NeMo-Guardrails/blob/develop/docs/user_guides/python-api.md#special-parameters).

            context: See [Action
                parameters](https://github.com/NVIDIA/NeMo-Guardrails/blob/develop/docs/user_guides/python-api.md#special-parameters).

            llm: See [Action
                parameters](https://github.com/NVIDIA/NeMo-Guardrails/blob/develop/docs/user_guides/python-api.md#special-parameters).

            config: See [Action
                parameters](https://github.com/NVIDIA/NeMo-Guardrails/blob/develop/docs/user_guides/python-api.md#special-parameters).

            function: Name of the feedback function to run.

            selectors: Selectors for the function. Can be provided either as
                strings to be parsed into lenses or lenses themselves.

            verbose: Print the values of the selectors before running feedback
                and print the result after running feedback.

        Returns:
            ActionResult: An action result containing the result of the feedback.

        Example:
            ```colang
            define subflow check language match
                $result = execute feedback(\
                    function="language_match",\
                    selectors={\
                    "text1":"action.context.last_user_message",\
                    "text2":"action.context.bot_message"\
                    }\
                )
                if $result < 0.8
                    bot inform language mismatch
                    stop
            ```
        
src/apps/nemo/trulens/apps/nemo/tru_rails.py