return self._final_outputs
    @final_outputs.setter
    def final_outputs(self, outputs: Optional[Dict[str, Any]]) -> None:
        # have access to intermediate steps by design in iterator,
        # so return only outputs may as well always be true.
        self._final_outputs = None
        if outputs:
            prepared_outputs: dict[str, Any] = self.agent_executor.prep_outputs(
                self.inputs, outputs, return_only_outputs=True
            )
            if self.include_run_info and self.run_manager is not None:
                logger.debug("Assign run key")
                prepared_outputs[RUN_KEY] = RunInfo(run_id=self.run_manager.run_id)
            self._final_outputs = prepared_outputs
    def __iter__(self: "AgentExecutorIterator") -> "AgentExecutorIterator":
        logger.debug("Initialising AgentExecutorIterator")
        self.reset()
        assert isinstance(self.callback_manager, CallbackManager)
        self.run_manager = self.callback_manager.on_chain_start(
            dumpd(self.agent_executor),
            self.inputs,
        )
        return self
    def __aiter__(self) -> "AgentExecutorIterator":
        """
        N.B. __aiter__ must be a normal method, so need to initialise async run manager
        on first __anext__ call where we can await it
        """
        logger.debug("Initialising AgentExecutorIterator (async)")
        self.reset()
        if self.agent_executor.max_execution_time:
            self.timeout_manager = asyncio_timeout(
                self.agent_executor.max_execution_time
            )
        else:
            self.timeout_manager = None
        return self
    def _on_first_step(self) -> None:
        """
        Perform any necessary setup for the first step of the synchronous iterator.
        """
        pass