Skip to content

feat: add graceful timeout and early session links for Slack/Discord webhooks#755

Open
kilo-code-bot[bot] wants to merge 1 commit intomainfrom
feat/webhook-timeout-and-session-links
Open

feat: add graceful timeout and early session links for Slack/Discord webhooks#755
kilo-code-bot[bot] wants to merge 1 commit intomainfrom
feat/webhook-timeout-and-session-links

Conversation

@kilo-code-bot
Copy link
Contributor

@kilo-code-bot kilo-code-bot bot commented Mar 3, 2026

Summary

  • Add a 750-second internal timeout to both Slack and Discord webhook handlers (below Vercel's 800s maxDuration) so users receive a friendly notification instead of a silent failure when Cloud Agent sessions run long
  • Send the Cloud Agent session link to the user as soon as the session is created, not after it completes — ephemeral in Slack, regular message in Discord
  • On timeout, notify the user that the session is still running and swap the processing reaction to complete

Changes

src/app/slack/webhook/route.ts

  • Add ENDPOINT_TIMEOUT_MS constant (750s)
  • Race processKiloBotMessage against the timeout; on timeout, post a friendly message and swap reactions
  • Send ephemeral session link via onCloudAgentSessionCreated callback as soon as session is spawned (moved from post-completion)

src/app/discord/webhook/route.ts

  • Add ENDPOINT_TIMEOUT_MS constant (750s)
  • Add buildSessionUrl, getDbSessionIdFromCloudAgentId, and postSessionLinkMessage helpers (mirrors Slack's existing pattern)
  • Race processDiscordBotMessage against the timeout; on timeout, post a friendly message and swap reactions
  • Send session link via onCloudAgentSessionCreated callback as soon as session is spawned

src/lib/slack-bot.ts

  • Extend processKiloBotMessage to accept an optional onCloudAgentSessionCreated callback
  • Invoke the callback when cloudAgentSessionId is set during tool execution

src/lib/discord-bot.ts

  • Extend processDiscordBotMessage to accept an optional onCloudAgentSessionCreated callback
  • Invoke the callback when cloudAgentSessionId is set during tool execution

Built for Remon Oldenbeuving by Kilo for Slack

…webhooks

Add a 750s internal timeout (below Vercel's 800s maxDuration) to both
the Slack and Discord webhook handlers so users get a friendly message
instead of a silent failure when Cloud Agent sessions run long.

When the timeout fires, post a message explaining the session is still
running and swap the processing reaction to complete.

Also send the Cloud Agent session link as soon as the session is created
(not after it finishes). For Slack this is an ephemeral message with a
View Session button; for Discord it's a regular reply with the session URL.
const timeoutMessage = truncateForDiscord(
'The Cloud Agent session is taking longer than expected. ' +
'Our endpoint is shutting down, but the session is still running. ' +
'Check the session link above to follow along.'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[WARNING]: Race condition — session link may not be posted yet when timeout message references it

The onCloudAgentSessionCreated callback fires postSessionLinkMessage as a fire-and-forget promise. That function performs 3 async operations (getInstallationByGuildId, getDbSessionIdFromCloudAgentId, postDiscordMessage) before the link actually appears in the channel.

If the timeout fires shortly after the session is created, this message says "Check the session link above to follow along" but the link message may not have been posted yet. The user would see the timeout message first, then the link message second — or the link message might fail entirely, leaving the user with no way to follow along.

Consider either:

  • awaiting the session link promise before posting the timeout message (if sessionLinkSent is true)
  • Changing the wording to not assume the link is "above"

const timeoutMessage = markdownToSlackMrkdwn(
'The Cloud Agent session is taking longer than expected. ' +
'Our endpoint is shutting down, but the session is still running. ' +
'Check the session link above to follow along.'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[WARNING]: Same race condition as Discord — the ephemeral session link may not have been delivered yet when this message references it

The onCloudAgentSessionCreated callback fires postSessionLinkEphemeral as fire-and-forget. If the timeout fires shortly after session creation, the user sees "Check the session link above" before the ephemeral link is actually posted.

Same mitigation options as the Discord side: await the pending link promise before posting the timeout message, or adjust the wording.

]);

console.log(`[SlackBot:Webhook] processSlackMessage (${event.type}) timed out gracefully`);
return;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[WARNING]: logSlackBotRequest is skipped on the timeout path

The early return here means timed-out requests are never logged via logSlackBotRequest (which runs at line 354). This creates a blind spot in admin debugging — the longest-running requests (the ones most likely to need investigation) won't appear in the logs.

Consider adding a logSlackBotRequest call with status: 'timeout' before returning.

/**
* Build the session URL for a cloud agent session based on the owner type
*/
function buildSessionUrl(dbSessionId: string, owner: Owner): string {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[SUGGESTION]: buildSessionUrl and getDbSessionIdFromCloudAgentId are now duplicated identically between the Discord and Slack webhook routes

Both functions have the exact same implementation. Consider extracting them into a shared module (e.g. src/lib/session-url.ts or similar) to keep them in sync.

});

const timeoutPromise = new Promise<null>(resolve => {
setTimeout(() => resolve(null), ENDPOINT_TIMEOUT_MS);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[SUGGESTION]: The setTimeout timer is never cleared on the normal (non-timeout) path

When botPromise resolves before the timeout, the 750-second timer continues running in the background. On a serverless platform this is unlikely to cause real issues (the function will be killed), but it's good hygiene to clear it:

let timeoutId: ReturnType<typeof setTimeout>;
const timeoutPromise = new Promise<null>(resolve => {
  timeoutId = setTimeout(() => resolve(null), ENDPOINT_TIMEOUT_MS);
});

const result = await Promise.race([botPromise, timeoutPromise]);
clearTimeout(timeoutId!);

Same applies to the Slack handler at src/app/slack/webhook/route.ts:265.

@kilo-code-bot
Copy link
Contributor Author

kilo-code-bot bot commented Mar 3, 2026

Code Review Summary

Status: 5 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 3
SUGGESTION 2
Issue Details (click to expand)

WARNING

File Line Issue
src/app/discord/webhook/route.ts 272 Race condition — session link may not be posted yet when timeout message says "Check the session link above"
src/app/slack/webhook/route.ts 277 Same race condition — ephemeral session link may not be delivered before timeout message references it
src/app/slack/webhook/route.ts 309 logSlackBotRequest is skipped on the timeout path — timed-out requests won't appear in admin debugging logs

SUGGESTION

File Line Issue
src/app/discord/webhook/route.ts 46 buildSessionUrl and getDbSessionIdFromCloudAgentId are duplicated identically between Discord and Slack webhook routes
src/app/discord/webhook/route.ts 260 setTimeout timer is never cleared on the normal (non-timeout) path; same in Slack handler at line 265
Files Reviewed (4 files)
  • src/app/discord/webhook/route.ts - 3 issues
  • src/app/slack/webhook/route.ts - 2 issues
  • src/lib/discord-bot.ts - 0 issues
  • src/lib/slack-bot.ts - 0 issues

Fix these issues in Kilo Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants