def run(
            self,
            audio_source: dict,
            text_to_synthesis: str,
            name_of_voice: str,
            is_authorized_to_clone_voice: bool,
            collection_id: str = "default",
            description="",
            cloned_voice_id=None,
            *args, 
            **kwargs) -> AgentResponse:
        """
        Clone the given audio file and synthesis the given text

        :param list sample_audios: The urls of the video given to clone
        :param str text_to_synthesis: The given text which needs to be synthesised in the cloned voice
        :param bool is_authorized_to_clone_voice: The flag which tells whether the user is authorised to clone the audio or not
        :param str name_of_voice: The name to be given to the cloned voice
        :param str descrption: The description about how the voice sounds like
        :param str collection_id: The collection id to store generated voice
        :param str cloned_voice_id: The voice ID generated from the previously given voice which can be used for cloning
        :param args: Additional positional arguments.
        :param kwargs: Additional keyword arguments.
        :return: The response containing information about voice cloning.
        :rtype: AgentResponse
        """
        try:
            if not is_authorized_to_clone_voice:
                return AgentResponse(status=AgentStatus.ERROR, message="Not authorised to clone the voice")
            
            audio_source = self.validate_audio_source(audio_source)

            ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
            if not ELEVENLABS_API_KEY:
                    raise Exception("Elevenlabs API key not present in .env")
            
            audio_gen_tool = ElevenLabsTool(api_key=ELEVENLABS_API_KEY)
            self.videodb_tool = VideoDBTool(collection_id=collection_id)

            if "audio_url" in audio_source:
                sample_file = self._download_audio_file(audio_source["audio_url"])
            
            if "video_id" in audio_source:
                sample_file = self._download_audio_from_video(audio_source)

            if not sample_file:
                return AgentResponse(status=AgentStatus.ERROR, message="Could'nt process the sample audios")

            if cloned_voice_id:
                self.output_message.actions.append("Using previously generated cloned voice")
                self.output_message.push_update()
                voice = audio_gen_tool.get_voice(voice_id=cloned_voice_id)
            else:
                self.output_message.actions.append("Cloning the voice")
                self.output_message.push_update()
                voice = audio_gen_tool.clone_audio(audio_files=[sample_file], name_of_voice=name_of_voice, description=description)

            if not voice:
                return AgentResponse(status=AgentStatus.ERROR, message="Failed to generate the voice clone")
            
            self.output_message.actions.append("Synthesising the given text")
            self.output_message.push_update()

            synthesised_audio = audio_gen_tool.synthesis_text(voice=voice, text_to_synthesis=text_to_synthesis)
            
            if not synthesised_audio:
                return AgentResponse(status=AgentStatus.ERROR, message="Failed to generate the voice clone")

            output_file_name = f"audio_clone_voice_output_{str(uuid.uuid4())}.mp3"
            output_path = f"{DOWNLOADS_PATH}/{output_file_name}"

            with open(output_path, "wb") as f:
                for chunk in synthesised_audio:
                    if chunk:
                        f.write(chunk)

            self.output_message.actions.append(
                f"Generated audio saved at <i>{output_path}</i>"
            )
            self.output_message.push_update()

            media = self.videodb_tool.upload(
                output_path, source_type="file_path", media_type="audio"
            )

            self.output_message.actions.append(
                f"Uploaded generated audio to VideoDB with Audio ID {media['id']}"
            )

            with open(os.path.abspath(output_path), "rb") as file:
                data_url = f"data:audio/mpeg;base64,{base64.b64encode(file.read()).decode('utf-8')}"
                text_content = TextContent(
                    agent_name=self.agent_name,
                    status=MsgStatus.success,
                    status_message="Here is your generated audio",
                    text=f"""Click <a href='{data_url}' download='{output_file_name}' target='_blank'>here</a> to download the audio
                    """,
                )

            self.output_message.content.append(text_content)
            self.output_message.push_update()
            self.output_message.publish()

            return AgentResponse(
                status=AgentStatus.SUCCESS,
                message=f"Agent {self.name} completed successfully.",
                data={
                    "cloned_voice_id": voice.voice_id,
                    "audio_id": media["id"]
                }
            )
        except Exception as e:
            logger.exception(f"Error in {self.agent_name}")
            text_content = TextContent(
                agent_name=self.agent_name,
                status=MsgStatus.error,
                status_message="Failed to generate audio",
            )
            self.output_message.content.append(text_content)
            self.output_message.push_update()
            self.output_message.publish()
            error_message = f"Agent failed with error {e}"
            return AgentResponse(status=AgentStatus.ERROR, message=error_message)

        Clone the given audio file and synthesis the given text

        :param list sample_audios: The urls of the video given to clone
        :param str text_to_synthesis: The given text which needs to be synthesised in the cloned voice
        :param bool is_authorized_to_clone_voice: The flag which tells whether the user is authorised to clone the audio or not
        :param str name_of_voice: The name to be given to the cloned voice
        :param str descrption: The description about how the voice sounds like
        :param str collection_id: The collection id to store generated voice
        :param str cloned_voice_id: The voice ID generated from the previously given voice which can be used for cloning
        :param args: Additional positional arguments.
        :param kwargs: Additional keyword arguments.
        :return: The response containing information about voice cloning.
        :rtype: AgentResponse
        
backend/director/agents/clone_voice.py