Repository: phidatahq/phidata
File: libs/agno/agno/agent/agent.py (Python)

Code before:
            # If the model response is a tool_call_started, add the tool call to the run_response
            elif (
                model_response_event.event == ModelResponseEvent.tool_call_started.value
            ):  # Add tool calls to the run_response
                tool_executions_list = model_response_event.tool_executions
                if tool_executions_list is not None:
                    # Add tool calls to the agent.run_response
                    if run_response.tools is None:
                        run_response.tools = tool_executions_list
                    else:
                        run_response.tools.extend(tool_executions_list)

                    # Yield each tool call started event
                    for tool in tool_executions_list:
                        yield self._handle_event(
                            create_tool_call_started_event(from_run_response=run_response, tool=tool), run_response
                        )

            # If the model response is a tool_call_completed, update the existing tool call in the run_response
            elif model_response_event.event == ModelResponseEvent.tool_call_completed.value:
                if model_response_event.updated_session_state is not None:
                    # update the session_state for RunOutput
                    if session_state is not None:
                        merge_dictionaries(session_state, model_response_event.updated_session_state)
                    # update the DB session
                    if session.session_data is not None:
                        merge_dictionaries(
                            session.session_data["session_state"], model_response_event.updated_session_state
                        )

                if model_response_event.images is not None:
                    for image in model_response_event.images:
                        self._add_image(image, run_response)

                if model_response_event.videos is not None:
                    for video in model_response_event.videos:
                        self._add_video(video, run_response)

                if model_response_event.audios is not None:
                    for audio in model_response_event.audios:
                        self._add_audio(audio, run_response)

                reasoning_step: Optional[ReasoningStep] = None

                tool_executions_list = model_response_event.tool_executions
                if tool_executions_list is not None:
                    # Update the existing tool call in the run_response
                    if run_response.tools:
                        # Create a mapping of tool_call_id to index
                        tool_call_index_map = {
                            tc.tool_call_id: i for i, tc in enumerate(run_response.tools) if tc.tool_call_id is not None

Review comment (suggestion):
```suggestion
                    if session.session_data is not None and session.session_data.get("session_state") is not None:
```

Code after:
                events_to_skip=self.events_to_skip,  # type: ignore
                store_events=self.store_events,
            )
            try:
                # Filter arguments to only include those that the hook accepts
                filtered_args = filter_hook_args(hook, all_args)

                if iscoroutinefunction(hook):
                    await hook(**filtered_args)
                else:
                    # Synchronous function
                    hook(**filtered_args)

                yield handle_event(  # type: ignore
                    run_response=run_response,
                    event=create_pre_hook_completed_event(
                        from_run_response=run_response,
                        run_input=run_input,
                        pre_hook_name=hook.__name__,
                    ),
                    events_to_skip=self.events_to_skip,  # type: ignore
                    store_events=self.store_events,
                )

            except (InputCheckError, OutputCheckError) as e:
                raise e
            except Exception as e:
                log_error(f"Pre-hook #{i + 1} execution failed: {str(e)}")
                log_exception(e)
            finally:
                # Reset global log mode incase an agent in the pre-hook changed it
                self._set_debug(debug_mode=debug_mode)

        # Update the input on the run_response
        run_response.input = run_input

    def _execute_post_hooks(
        self,
        hooks: Optional[List[Callable[..., Any]]],
        run_output: RunOutput,
        session: AgentSession,
        session_state: Optional[Dict[str, Any]] = None,
        dependencies: Optional[Dict[str, Any]] = None,
        metadata: Optional[Dict[str, Any]] = None,
        user_id: Optional[str] = None,
        debug_mode: Optional[bool] = None,
        **kwargs: Any,
    ) -> Iterator[RunOutputEvent]:
        """Execute multiple post-hook functions in succession."""
        if hooks is None:
            return