Skip to content

refactor(bot): persist Thread/Message state for callback rehydration#3127

Open
RSO wants to merge 5 commits intomainfrom
RSO/dust-ferryboat
Open

refactor(bot): persist Thread/Message state for callback rehydration#3127
RSO wants to merge 5 commits intomainfrom
RSO/dust-ferryboat

Conversation

@RSO
Copy link
Copy Markdown
Contributor

@RSO RSO commented May 8, 2026

Summary

Hardens Thread/Message re-instantiation so cloud-agent callbacks can reliably resume where they left off when the agent comes back. When a bot request is created, the Thread and Message are now serialized via their toJSON() shapes and stored in the bot's StateAdapter keyed by botRequestId (24h TTL). The cloud-agent session callback (bot-session-callback/[botRequestId]/route.ts) rehydrates them via ThreadImpl.fromJSON / Message.fromJSON instead of best-effort re-fetching the original platform message through the adapter — which could fail or lose the author/context entirely.

The SerializedThread / SerializedMessage Zod schemas previously inlined in lib/bot-identity.ts are extracted into the new lib/bot/message-state.ts module and reused there.

Verification

  • Triggered a cloud-agent session via Slack mention, let it complete, and confirmed the callback continuation prompt is built using the rehydrated message author rather than the fallback "Cloud Agent Callback" identity.

Visual Changes

N/A

Reviewer Notes

  • New Redis-backed state entries under the bot-request-message-state: prefix; TTL is 24h.
  • processLinkedMessage now requires a state: StateAdapter argument — both call sites (createKiloBot mention handler and the link-account reprocessing path) pass bot.getState().
  • getRehydratedBotRequestMessageState throws if no entry is found; the callback route relies on the bot request having been created through the new write path. Existing in-flight requests created before deploy will fall through to that error — acceptable given the 24h TTL window.

Store serialized Thread and Message state when creating a bot request and
rehydrate them in the cloud-agent session callback handler. This replaces
the prior approach of re-fetching the platform message via the adapter,
which could fail or lose context when the cloud agent returns. Extracts
the SerializedThread/SerializedMessage Zod schemas into a shared
message-state module reused by bot-identity.
Comment thread apps/web/src/lib/bot/run.ts
Comment thread apps/web/src/app/api/internal/bot-session-callback/[botRequestId]/route.ts Outdated
@kilo-code-bot
Copy link
Copy Markdown
Contributor

kilo-code-bot Bot commented May 8, 2026

Code Review Summary

Status: 1 Issue Found | Recommendation: Address before merge

Overview

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

WARNING

File Line Issue
apps/web/src/lib/bot/run.ts 35 Full serialized message/thread state is still stored for every bot request, creating unnecessary 24h Redis memory retention for requests that never spawn callbacks.
Resolved Since Last Review
File Line Issue
apps/web/src/app/api/internal/bot-session-callback/[botRequestId]/route.ts 874 Missing/expired message state is now caught and the bot request is marked as error instead of leaving the request pending.
Other Observations (not in diff)

Issues found in unchanged code that cannot receive inline comments:

File Line Issue
N/A N/A N/A
Files Reviewed (1 file)
  • apps/web/src/app/api/internal/bot-session-callback/[botRequestId]/route.ts - 0 new issues, 1 previous issue resolved
  • apps/web/src/lib/bot/run.ts - not re-reviewed; 1 carried-forward issue

Fix these issues in Kilo Cloud


Reviewed by gpt-5.5-20260423 · 498,005 tokens

RSO added 4 commits May 8, 2026 10:35
When `getRehydratedBotRequestMessageState` throws (Redis entry missing,
expired, or failed state write), the callback previously only surfaced
the error via the outer catch and left the bot_request stuck in pending.
Catch the rehydration failure explicitly, capture it to Sentry with
targeted tags, and mark the bot_request as error so it does not linger.
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.

1 participant