def update_call_info(rets, final=True):
                """Notify the app of the call and let it update the record if
                needed.

                `final` is passed to the new record handler in the app and tells
                it whether to the record is ready to run feedback.
                """

                # (re) generate end_time here because cases where the
                # initial end_time was just to produce an awaitable/lazy
                # before being awaited. If a stream is used, this will
                # update the end_time to the last chunk.
                end_time = datetime.now()

                record_app_args = dict(
                    call_id=call_id,
                    args=nonself,
                    perf=base_schema.Perf(
                        start_time=start_time, end_time=end_time
                    ),
                    pid=os.getpid(),
                    tid=th.get_native_id(),
                    rets=json_utils.jsonify(rets),
                    error=error_str if error is not None else None,
                )
                # End of run wrapped block.

                # Now record calls to each context.
                for ctx in contexts:
                    stack = stacks[ctx]

                    # Note that only the stack differs between each of the records in this loop.
                    record_app_args["stack"] = stack
                    call = record_schema.RecordAppCall(**record_app_args)
                    ctx.add_call(call)

                    # If stack has only 1 thing on it, we are looking at a "root
                    # call". Create a record of the result and notify the app:

                    existing_record = records.get(ctx, None)

                    if tally is None:
                        cost = base_schema.Cost()
                    else:
                        cost = tally()  # get updated cost

                    if len(stack) == 1 or existing_record is not None:
                        # If this is a root call, notify app to add the completed record
                        # into its containers:

                        records[ctx] = ctx.app.on_add_record(
                            ctx=ctx,
                            func=func,
                            sig=sig,
                            bindings=bindings,
                            ret=rets,
                            error=error,
                            perf=base_schema.Perf(
                                start_time=start_time, end_time=end_time
                            ),
                            cost=cost,
                            existing_record=existing_record,
                            final=final,
                        )

                if error is not None:
                    raise error

                return rets
Notify the app of the call and let it update the record if
                needed.

                `final` is passed to the new record handler in the app and tells
                it whether to the record is ready to run feedback.
                
src/core/trulens/core/instruments.py