Skip to content

Commit 30c3806

Browse files
committed
feat: cancelling tasks
1 parent d39cd97 commit 30c3806

6 files changed

Lines changed: 447 additions & 42 deletions

File tree

index.js

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,13 @@ async function centralOrchestrator(question, userId, chatId = 1, isFollowUp = fa
182182
contextManager.resetContext(userId, chatId);
183183
}
184184

185+
// Clear any previous cancellation history when starting a new task
186+
contextManager.clearCancellationHistory(userId, chatId);
187+
188+
// Create AbortController for cancellation support
189+
const abortController = new AbortController();
190+
contextManager.setCancellationToken(abortController, userId, chatId);
191+
185192
// Set task as running only once after context is initialized/reset
186193
contextManager.setTaskRunning(true, userId, chatId);
187194

@@ -192,12 +199,22 @@ async function centralOrchestrator(question, userId, chatId = 1, isFollowUp = fa
192199
// Set the question in context
193200
contextManager.setQuestion(question, userId, chatId);
194201

202+
// Check for cancellation
203+
if (contextManager.isTaskCancelled(userId, chatId)) {
204+
throw new Error('Task cancelled by user');
205+
}
206+
195207
// Generate planning prompt
196208
const history = contextManager.getHistoryWithChatId(userId, chatId);
197209
const prompt = await prompts.generatePlanningPrompt(question, history, userId);
198210

199211
io.to(`user:${userId}`).emit('status_update', { userId, chatId, status: 'Planning task execution' });
200212

213+
// Check for cancellation
214+
if (contextManager.isTaskCancelled(userId, chatId)) {
215+
throw new Error('Task cancelled by user');
216+
}
217+
201218
// Get plan from AI using planning model
202219
let planObject = await ai.callAI(prompt, question, history, undefined, true, "planning", userId, chatId);
203220

@@ -212,15 +229,27 @@ async function centralOrchestrator(question, userId, chatId = 1, isFollowUp = fa
212229
} catch (error) {
213230
console.error("Critical error in orchestration:", error.message);
214231

215-
io.to(`user:${userId}`).emit('task_error', { userId, chatId, error: error.message });
232+
// Check if this was a cancellation
233+
const isCancelled = error.message === 'Task cancelled by user';
234+
235+
// Clean up task state
236+
contextManager.setTaskRunning(false, userId, chatId);
237+
contextManager.clearCancellationToken(userId, chatId);
238+
239+
// Send appropriate message to client
240+
if (isCancelled) {
241+
io.to(`user:${userId}`).emit('task_cancelled', { userId, chatId, message: 'Task cancelled successfully' });
242+
} else {
243+
io.to(`user:${userId}`).emit('task_error', { userId, chatId, error: error.message });
244+
}
216245

217246
try {
218247
await cleanupUserResources(userId);
219248
} catch (cleanupError) {
220249
console.error("Error during cleanup:", cleanupError.message);
221250
}
222251

223-
return `Critical error occurred during execution: ${error.message}`;
252+
return isCancelled ? 'Task cancelled by user' : `Critical error occurred during execution: ${error.message}`;
224253
}
225254
}
226255

@@ -269,6 +298,7 @@ async function handleDirectAnswer(planObject, question, userId, chatId) {
269298

270299
// Mark task as no longer running
271300
contextManager.setTaskRunning(false, userId, chatId);
301+
contextManager.clearCancellationToken(userId, chatId);
272302

273303
await cleanupUserResources(userId);
274304
return planObject.answer;
@@ -368,6 +398,11 @@ function setupScreenshotInterval(plan, userId, chatId) {
368398
*/
369399
async function executeSteps(plan, question, userId, chatId) {
370400
while (contextManager.getCurrentStepIndex(userId, chatId) < plan.length) {
401+
// Check for cancellation before each step
402+
if (contextManager.isTaskCancelled(userId, chatId)) {
403+
throw new Error('Task cancelled by user');
404+
}
405+
371406
const currentStepIndex = contextManager.getCurrentStepIndex(userId, chatId);
372407
const step = plan[currentStepIndex];
373408

@@ -693,6 +728,7 @@ async function finalizeAndReturn(question, plan, userId, chatId) {
693728

694729
// Mark task as no longer running
695730
contextManager.setTaskRunning(false, userId, chatId);
731+
contextManager.clearCancellationToken(userId, chatId);
696732

697733
await cleanupUserResources(userId);
698734
return finalOutput;

0 commit comments

Comments
 (0)