| 
									
										
										
										
											2024-12-19 17:00:32 +08:00
										 |  |  | # tasks.py | 
					
						
							|  |  |  | import asyncio | 
					
						
							|  |  |  | from typing import Dict | 
					
						
							|  |  |  | from uuid import uuid4 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # A dictionary to keep track of active tasks | 
					
						
							|  |  |  | tasks: Dict[str, asyncio.Task] = {} | 
					
						
							| 
									
										
										
										
											2025-04-13 11:51:02 +08:00
										 |  |  | chat_tasks = {} | 
					
						
							| 
									
										
										
										
											2024-12-19 17:00:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-13 11:51:02 +08:00
										 |  |  | def cleanup_task(task_id: str, id=None): | 
					
						
							| 
									
										
										
										
											2024-12-19 17:00:32 +08:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     Remove a completed or canceled task from the global `tasks` dictionary. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     tasks.pop(task_id, None)  # Remove the task if it exists | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-13 11:51:02 +08:00
										 |  |  |     # If an ID is provided, remove the task from the chat_tasks dictionary | 
					
						
							|  |  |  |     if id and task_id in chat_tasks.get(id, []): | 
					
						
							|  |  |  |         chat_tasks[id].remove(task_id) | 
					
						
							|  |  |  |         if not chat_tasks[id]:  # If no tasks left for this ID, remove the entry | 
					
						
							|  |  |  |             chat_tasks.pop(id, None) | 
					
						
							| 
									
										
										
										
											2024-12-19 17:00:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-13 11:51:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | def create_task(coroutine, id=None): | 
					
						
							| 
									
										
										
										
											2024-12-19 17:00:32 +08:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     Create a new asyncio task and add it to the global task dictionary. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     task_id = str(uuid4())  # Generate a unique ID for the task | 
					
						
							|  |  |  |     task = asyncio.create_task(coroutine)  # Create the task | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Add a done callback for cleanup | 
					
						
							| 
									
										
										
										
											2025-04-13 11:51:02 +08:00
										 |  |  |     task.add_done_callback(lambda t: cleanup_task(task_id, id)) | 
					
						
							| 
									
										
										
										
											2024-12-19 17:00:32 +08:00
										 |  |  |     tasks[task_id] = task | 
					
						
							| 
									
										
										
										
											2025-04-13 11:51:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # If an ID is provided, associate the task with that ID | 
					
						
							|  |  |  |     if chat_tasks.get(id): | 
					
						
							|  |  |  |         chat_tasks[id].append(task_id) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         chat_tasks[id] = [task_id] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-19 17:00:32 +08:00
										 |  |  |     return task_id, task | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def get_task(task_id: str): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Retrieve a task by its task ID. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     return tasks.get(task_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def list_tasks(): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     List all currently active task IDs. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     return list(tasks.keys()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-13 11:51:02 +08:00
										 |  |  | def list_task_ids_by_chat_id(id): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     List all tasks associated with a specific ID. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     return chat_tasks.get(id, []) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-19 17:00:32 +08:00
										 |  |  | async def stop_task(task_id: str): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Cancel a running task and remove it from the global task list. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     task = tasks.get(task_id) | 
					
						
							|  |  |  |     if not task: | 
					
						
							|  |  |  |         raise ValueError(f"Task with ID {task_id} not found.") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     task.cancel()  # Request task cancellation | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         await task  # Wait for the task to handle the cancellation | 
					
						
							|  |  |  |     except asyncio.CancelledError: | 
					
						
							|  |  |  |         # Task successfully canceled | 
					
						
							|  |  |  |         tasks.pop(task_id, None)  # Remove it from the dictionary | 
					
						
							|  |  |  |         return {"status": True, "message": f"Task {task_id} successfully stopped."} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return {"status": False, "message": f"Failed to stop task {task_id}."} |