From d798b0f3602c7ab1e978331596b609bba36933cb Mon Sep 17 00:00:00 2001 From: Wells Bunker Date: Thu, 25 Sep 2025 15:05:36 -0600 Subject: [PATCH] If slack message is canceled send a message instead of fail and retry --- .../slack-agent-task/slack-agent-task.ts | 93 ++++++++++++++++++- 1 file changed, 91 insertions(+), 2 deletions(-) diff --git a/apps/trigger/src/tasks/slack-agent-task/slack-agent-task.ts b/apps/trigger/src/tasks/slack-agent-task/slack-agent-task.ts index 4ebb58267..f5979ec69 100644 --- a/apps/trigger/src/tasks/slack-agent-task/slack-agent-task.ts +++ b/apps/trigger/src/tasks/slack-agent-task/slack-agent-task.ts @@ -383,7 +383,12 @@ export const slackAgentTask: ReturnType< const maxRapidPolls = 20; // 20 attempts = 20 seconds total let rapidPollCount = 0; let isComplete = false; - let analystResult: { ok: boolean; output?: unknown; error?: unknown } | null = null; + let analystResult: { + ok: boolean; + output?: unknown; + error?: unknown; + canceled?: boolean; + } | null = null; while (rapidPollCount < maxRapidPolls && !hasStartedRunning && !isComplete) { await wait.for({ seconds: rapidPollInterval / 1000 }); @@ -491,6 +496,8 @@ export const slackAgentTask: ReturnType< isComplete = true; if (run.status === 'COMPLETED') { analystResult = { ok: true, output: run.output }; + } else if (run.status === 'CANCELED') { + analystResult = { ok: false, canceled: true }; } else { analystResult = { ok: false, error: run.error || 'Task failed' }; } @@ -605,10 +612,12 @@ export const slackAgentTask: ReturnType< if (run.status === 'COMPLETED') { isComplete = true; analystResult = { ok: true, output: run.output }; + } else if (run.status === 'CANCELED') { + isComplete = true; + analystResult = { ok: false, canceled: true }; } else if ( run.status === 'SYSTEM_FAILURE' || run.status === 'CRASHED' || - run.status === 'CANCELED' || run.status === 'TIMED_OUT' ) { isComplete = true; @@ -627,6 +636,86 @@ export const slackAgentTask: ReturnType< analystResult = { ok: false, error: 'Task timed out' }; } + if (analystResult && !analystResult.ok && analystResult.canceled) { + logger.log('Analyst task was canceled mid-execution', { + runId: analystHandle.id, + }); + + try { + if (progressMessageTs) { + await messagingService.deleteMessage( + accessToken, + chatDetails.slackChannelId, + progressMessageTs + ); + } + + await removeReaction({ + accessToken, + channelId: chatDetails.slackChannelId, + messageTs: mentionMessageTs, + emoji: 'hourglass_flowing_sand', + }); + } catch (error) { + logger.warn( + 'Error cleaning up initial message and reaction after canceled analyst task', + { + messageTs: progressMessageTs, + error: error instanceof Error ? error.message : 'Unknown error', + } + ); + } + + try { + const canceledMessage = + 'Your request was canceled mid-execution. If this was a mistake, please ask your question again.'; + const messageBlocks = [ + { + type: 'section' as const, + text: { + type: 'plain_text' as const, + text: canceledMessage, + }, + }, + { + type: 'actions' as const, + elements: [ + { + type: 'button' as const, + text: { + type: 'plain_text' as const, + text: 'Open in Buster', + emoji: false, + }, + url: `${busterUrl}/app/chats/${payload.chatId}`, + }, + ], + }, + ]; + const completeCanceledMessage = { + text: canceledMessage, + thread_ts: chatDetails.slackThreadTs, + blocks: messageBlocks, + }; + + await messagingService.sendMessage( + accessToken, + chatDetails.slackChannelId, + completeCanceledMessage + ); + } catch (error) { + logger.warn('Failed to send canceled message to Slack', { + error: error instanceof Error ? error.message : 'Unknown error', + }); + } + + return { + success: false, + messageId: '', + triggerRunId: '', + }; + } + // Handle analyst task result if (!analystResult || !analystResult.ok) { // If analyst task failed, notify the user