def run(
            self,
            sample_video,
            video_ids: list[str],
            name_of_voice: str,
            is_authorized_to_clone_voice: bool,
            collection_id: str,
            description="",
            cloned_voice_id=None,
            *args, 
            **kwargs) -> AgentResponse:
        """
        Clone the given audio file and synthesis the given text

        :param sample_video: An boject containing video_id and strt_time for taking sample
        :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 list[str] video_ids: The IDs of the videos from which we retrieve the transcript.
        :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")

            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)


            self.output_message.actions.append("Getting the sample video's stream")
            self.output_message.push_update()
            stream_url = self.videodb_tool.generate_video_stream(sample_video["video_id"], [(sample_video.get("start_time", 0),sample_video.get("end_time", 90))]) 

            self.output_message.actions.append("Getting the sample video's download URL")
            self.output_message.push_update()
            download_response = self.videodb_tool.download(stream_url, name="audio_sample_video")
            if download_response.get("status") == "done":
                download_url = download_response.get("download_url")
            else:
                raise Exception("Couldn't find the video download url")
            
            self.output_message.actions.append("Downloading the sample video")
            self.output_message.push_update()
            video_path = self._download_video_file(download_url)

            if not video_path:
                raise Exception("Couldn't fetch the video for sampling")
            
            sample_audio = self._extract_audio_from_video(video_path=video_path)

            if not sample_audio:
                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_audio], name_of_voice=name_of_voice, description=description)

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

            for video_id in video_ids:
                video = self.videodb_tool.get_video(video_id=video_id)
                text_to_synthesis = self._get_transcript(video_id=video_id)
                self.output_message.actions.append(f"Synthesising {video['name']}'s transcript in cloned voice")
                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)


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

                if not audio:
                    error_content = TextContent(
                        status=MsgStatus.progress,
                        status_message=f"Adding cloned voice to {video['name']} failed",
                        agent_name=self.agent_name
                    )
                    self.output_message.content.append(error_content)
                    self.output_message.push_update()
                    continue

                video_content = VideoContent(
                    status=MsgStatus.progress,
                    status_message=f"Adding cloned voice to {video['name']}",
                    agent_name=self.agent_name
                )

                self.output_message.content.append(video_content)
                self.output_message.push_update()


                self.timeline = self.videodb_tool.get_and_set_timeline()

                stream_url = self._generate_overlay(video_id, audio_id=audio['id'])

                video_content.video = VideoData(stream_url=stream_url)
                video_content.status = MsgStatus.success
                video_content.status_message = f"Here is your video {video['name']} with the cloned voice"

                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": audio["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 the final video",
            )
            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 sample_video: An boject containing video_id and strt_time for taking sample
        :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 list[str] video_ids: The IDs of the videos from which we retrieve the transcript.
        :param args: Additional positional arguments.
        :param kwargs: Additional keyword arguments.
        :return: The response containing information about voice cloning.
        :rtype: AgentResponse
        
backend/director/agents/voice_replacement.py