def wrap_until_eager(
    obj,
    on_eager: Optional[Callable[[Any], T]] = None,
    context_vars: Optional[ContextVarsOrValues] = None,
) -> T | Sequence[T]:
    """Wrap a lazy value in one that will call callbacks one the final non-lazy
    values.

    Arts:
        obj: The lazy value.

        on_eager: The callback to call with the final value of the wrapped
            generator or the result of an awaitable. This should return the
            value or a wrapped version.

        context_vars: The context variables to copy over to the wrapped
            generator. If None, all context variables are taken with their
            present values. See
            [with_context][trulens.core.utils.python.with_context].
    """

    def rewrap(obj_):
        if is_lazy(obj_):
            return wrap_lazy(
                obj_, wrap=rewrap, on_done=rewrap, context_vars=context_vars
            )

        if on_eager is not None:
            return on_eager(obj_)

        return obj_

    return rewrap(obj)
Wrap a lazy value in one that will call callbacks one the final non-lazy
    values.

    Arts:
        obj: The lazy value.

        on_eager: The callback to call with the final value of the wrapped
            generator or the result of an awaitable. This should return the
            value or a wrapped version.

        context_vars: The context variables to copy over to the wrapped
            generator. If None, all context variables are taken with their
            present values. See
            [with_context][trulens.core.utils.python.with_context].
    
src/core/trulens/core/utils/python.py