async def change_in_canvas(self, new_text_of_part: str, part_definition: str) -> str:
        """Change the text of a part of the canvas"""
        from upsonic import Task, Direct, UpsonicClient
        
        client = UpsonicClient("localserver", debug=True, main_port=7542, tools_port=8088)
        direct = Direct(model=self.llm_model, client=client)
        
        current_canvas = self.get_current_state_of_canvas()
        
        # For empty canvas, just save the new content directly
        if current_canvas == "Empty Canvas" or current_canvas == "":
            print("******** SAVING CANVAS *********")
            print(new_text_of_part)
            self._save_canvas(new_text_of_part)
            return new_text_of_part

        # For existing canvas, use LLM to modify or append content
        prompt = (
            f"I have a text document with the following content:\n\n{current_canvas}\n\n"
            f"If there is a line or section that contains '{part_definition}', replace it with exactly:\n"
            f"{new_text_of_part}\n\n"
            f"If the document does NOT contain a section with '{part_definition}', append the following as a new section at the end of the document:\n"
            f"{new_text_of_part}\n\n"
            f"Return only the complete updated text document without any explanations, code blocks, or additional formatting."
        )
        
        task = Task(prompt)
        result = await direct.do_async(task)
        print("******** SAVING CANVAS *********")
        print(result)
        self._save_canvas(result)
        return result
Change the text of a part of the canvas
src/upsonic/tools.py