def parse(self, output: str, is_streaming: bool = False) -> BaseReasoningStep:
        """
        Parse output from the ReAct agent.

        Args:
            output (str): The output from the ReAct agent.
            is_streaming (bool): Whether the output is being streamed.

        Returns:
            BaseReasoningStep: The parsed reasoning step.

        Raises:
            ValueError: If the output cannot be parsed.

        """
        if "Thought:" not in output:
            return ResponseReasoningStep(
                thought="(Implicit) I can answer without any more tools!",
                response=output,
                is_streaming=is_streaming,
            )

        if "Answer:" in output:
            thought, answer = extract_final_response(output)
            return ResponseReasoningStep(
                thought=thought, response=answer, is_streaming=is_streaming
            )

        if "Action:" in output:
            thought, action, action_input = extract_tool_use(output)
            if action in self.functionality_list:
                if action not in self.called_functionalities:
                    (
                        message_type,
                        function_schema,
                    ) = self.spoke_operator.probe_functionality(action)

                    if (
                        message_type != "function_probe_response"
                        or function_schema is None
                    ):
                        message = f"Could not probe {action} functionality. YOU MUST NOT PROBE {action} AGAIN!"

                        return ActionReasoningStep(
                            thought="Use message_spoke to deliver instructions.",
                            action="message_spoke",
                            action_input={"message": message},
                        )
                    self.called_functionalities[action] = {}
                    self.called_functionalities[action]["function_schema"] = (
                        function_schema
                    )
                else:
                    function_schema = self.called_functionalities[action][
                        "function_schema"
                    ]
                    message = f'Use the tool "{action}" with the formatted input strictly following the tool parameter dictionary: "{function_schema!s}"'
                    return ActionReasoningStep(
                        thought="",
                        action="message_spoke",
                        action_input={"message": message},
                    )

                message_type, response = self.spoke_operator.make_request(
                    action, action_input
                )
                if message_type != "app_response":
                    message = f"Could not make request to {action}. YOU MUST NOT REQUEST {action} AGAIN!"
                    return ActionReasoningStep(
                        thought="",
                        action="message_spoke",
                        action_input={"message": message},
                    )
                    # Use message_spoke to deliver instructions.
                message = f"Response from {action}: {response!s}"
                return ActionReasoningStep(
                    thought="",
                    action="message_spoke",
                    action_input={"message": message},
                )

            else:
                return parse_action_reasoning_step(output)

        raise ValueError(f"Could not parse output: {output}")

        Parse output from the ReAct agent.

        Args:
            output (str): The output from the ReAct agent.
            is_streaming (bool): Whether the output is being streamed.

        Returns:
            BaseReasoningStep: The parsed reasoning step.

        Raises:
            ValueError: If the output cannot be parsed.

        
llama-index-packs/llama-index-packs-secgpt/llama_index/packs/secgpt/spoke_parser.py