/** * Task cancellation utilities for long-running generation processes. */ import { toast } from 'sonner'; const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || '/api'; export interface TaskCancellationResponse { success: boolean; message?: string; error?: string; } /** * Cancel a task by its ID */ export async function cancelTask(taskId: string): Promise { try { const url = `${API_BASE_URL}/tasks/${taskId}`; const response = await fetch(url, { method: 'DELETE', headers: { 'Content-Type': 'application/json', }, }); if (!response.ok) { if (response.status === 404) { return { success: false, error: 'Task not found or already completed', }; } const errorData = await response.json().catch(() => ({})); return { success: false, error: errorData.error || `Failed to cancel task: ${response.statusText}`, }; } const data = await response.json(); return { success: true, message: data.message || 'Task cancelled successfully', }; } catch (error) { console.error('Error cancelling task:', error); return { success: false, error: error instanceof Error ? error.message : 'Network error while cancelling task', }; } } /** * Cancel a task with user feedback */ export async function cancelTaskWithFeedback(taskId: string, taskDescription: string = 'task'): Promise { try { const result = await cancelTask(taskId); if (result.success) { toast.success(result.message || `${taskDescription} cancelled successfully`); return true; } else { toast.error(result.error || `Failed to cancel ${taskDescription}`); return false; } } catch (error) { console.error('Error cancelling task with feedback:', error); toast.error(`Failed to cancel ${taskDescription}`); return false; } } /** * Hook-style function for creating a cancellation handler */ export function useCancellationHandler(taskId: string | null, onCancel?: () => void) { return async () => { if (!taskId) { console.warn('No task ID available for cancellation'); return false; } const success = await cancelTaskWithFeedback(taskId, 'generation'); if (success && onCancel) { onCancel(); } return success; }; } /** * Utility for handling WebSocket cancellation events */ export function handleWebSocketCancellation( taskId: string, onCancelled: () => void, taskDescription: string = 'task' ) { // This will be implemented when we add WebSocket support return (event: any) => { if (event.task_id === taskId && event.type === 'task_cancelled') { toast.info(`${taskDescription} was cancelled`); onCancelled(); } }; }