Open
Conversation
Contributor
Code Review SummaryStatus: 7 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
Other Observations (not in diff)Issues found in unchanged code that cannot receive inline comments:
Files Reviewed (3 files)
Fix these issues in Kilo Cloud Reviewed by gpt-5.5-20260423 · 1,791,846 tokens |
This was referenced Apr 29, 2026
St0rmz1
reviewed
May 4, 2026
St0rmz1
reviewed
May 4, 2026
St0rmz1
reviewed
May 4, 2026
jeanduplessis
approved these changes
May 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR completes the Stream Chat cutover to first-party Kilo Chat across web, mobile, shared packages, and the Worker services that back KiloClaw chat. It introduces the Kilo Chat service as the canonical chat API, Event Service as the realtime/presence transport, Notifications as the badge/push owner, and KiloClaw runtime/plugin changes needed to run the new chat path.
High-level breaking backwards compatibility changes
POST /connect-ticketfollowed by/connect?ticket=...with thekilo.events.v1subprotocol.lastSeenMessageId, delete-style mutations return JSON instead of204, and strict clients must handle canonicalmessage,conversation, cursor, reply, action, and reaction-operation fields.sandboxId/conversationIdKilo Chat payloads. The old SQLchannel_badge_countstable is dropped and unread badge state moves to per-user Notification DO buckets without a backfill.Web app
/claw/chat/[conversationId]and/organizations/[id]/claw/chat/[conversationId]routes, with guards for missing instances and mismatched sandbox conversations.EventServiceProvider, reusing one Event Service and Kilo Chat client across the app.Compatibility notes:
/claw/chatand/organizations/[id]/claw/chatnow render Kilo Chat instead of the old Stream Chat channel UI./claw/kilo-chatand/claw/kilo-chat/:conversationIdto/claw/chatand/claw/chat/:conversationId, with equivalent organization redirects.GET /api/kiloclaw/chat-credentials,kiloclaw.getStreamChatCredentials,kiloclaw.sendChatMessage,organizations.kiloclaw.getStreamChatCredentials, andorganizations.kiloclaw.sendChatMessage./api/kilo-chat/tokenandkiloChat.getTokennow return{ token, expiresAt, userId }.Mobile app
Compatibility notes:
/(app)/chat/[instance-id]to/(app)/chat/[sandbox-id]and/(app)/chat/[sandbox-id]/[conversation-id]. Existing one-segment chat links now land on the conversation list.instanceId-based chat/lifecycle shapes to shared notifications payloads: chat messages requiretype: "chat.message",sandboxId,conversationId, andmessageId; lifecycle notifications usesandboxId.KILO_CHAT_URL,EVENT_SERVICE_URL, andNOTIFICATIONS_URL.Shared packages and data model
@kilocode/kilo-chat-hooks, a shared React Query hook layer for conversations, messages, bot status, optimistic mutations, event-driven cache updates, mark-read retry state, and pending action state.@kilocode/kilo-chatschemas/types/client contracts for reply snapshots, action resolution state, mark-read results, reaction removal results, execute-action results, canonical create responses, and paginated message pages.replyTo, reactionoperationId, and fullconversation.createddata.@kilocode/event-servicefor connection tickets, ref-counted context subscriptions, KiloClaw event/presence context builders, and retry/unauthorized recovery.@kilocode/notificationswith shared badge bucket helpers, push notification data schemas, and notification RPC schemas.verifyKiloBearerAgainstCurrentPepperin@kilocode/worker-utils/kilo-token-authto validate token environment and current user pepper.channel_badge_countsand generated Drizzle metadata, plus remaining Stream Chat package/patch lockfile wiring.Compatibility notes:
channel_badge_countsandChannelBadgeCountare removed; unread/badge state moves to badge bucket contracts such askiloclaw:<sandboxId>andkiloclaw:<sandboxId>:<conversationId>.markConversationRead(conversationId)now requires{ lastSeenMessageId }and returns{ ok, applied, lastReadAt, badgeClear };removeReactionreturns{ removed, id };executeActionreturns updated message content/resolution.message, create-conversation responses includeconversation, message events includereplyTo, conversation-created events includeconversation, and reaction events includeoperationId.hasMoreandnextCursor.Kilo Chat service
lastReadAt, and notification badge clearing.NOTIFICATIONSservice binding.conversation.read, andreplyTodata onmessage.created.ConversationDO, skips textless message webhooks, and reports/reverts failed message/action delivery.Backwards compatibility:
WORKER_ENVand carry the current user pepper; they do not need a kilo-chat-specific token source.POST /v1/conversations/:id/mark-readnow requires{ lastSeenMessageId }and returns{ ok, applied, lastReadAt, badgeClear }; it can return503if badge clearing fails.200JSON instead of204; reaction delete returns{ removed, id }.dedupe: "fresh"field.typing.stop, andconversation.readis targeted to the relevant user.WORKER_ENV,NOTIFICATIONS, and working Hyperdrive access for auth, ownership, and sandbox labels.Event service
POST /connect-ticketaccepts a bearer Kilo JWT, thenGET /connect?ticket=...consumes the ticket for the WebSocket upgrade.ConnectionTicketDOwith 30-second TTL, consume-once semantics, and alarm cleanup.kilo.events.v1./connect-ticket, includingAuthorization, and allowshttp://localhost:3000for local development.isUserInContext(userId, context), backed byUserSessionDO.hasContext, so notification fanout can suppress pushes for live subscribers.CONNECTION_TICKET_DO,HYPERDRIVE, andWORKER_ENV.Backwards compatibility:
Sec-WebSocket-Protocol: kilo.jwt.<base64url-jwt>must migrate to/connect-ticket,/connect?ticket=..., andkilo.events.v1.CONNECTION_TICKET_DO,HYPERDRIVE,WORKER_ENV, and the new Durable Object migration before the ticket flow works./healthremains public./connectstill requires WebSocket upgrade but now rejects missing/invalid tickets instead of missing/invalid JWT subprotocols./connect-ticketis public but bearer-authenticated.Notifications service
/v1/badgesand/v1/badges/mark-readroutes for mobile badge hydration and read clearing.channel_badge_countsinto per-userNotificationChannelDObucket storage.sandboxId.NEXTAUTH_SECRET,WORKER_ENV, andEVENT_SERVICE.Backwards compatibility:
/webhooks/stream-chatis removed; existing Stream Chat webhook delivery must be disabled or migrated to the new RPC producers./v1/*badge routes requireAuthorization: Bearer <Kilo JWT>and return{ buckets }or{ badgeCount }; no unauthenticated badge access is supported.sendInstanceLifecycleNotificationno longer usesinstanceIdin request/push data and now returnsticketErrors.type: "chat.message"withsandboxId,conversationId, andmessageId; lifecycle data usessandboxId.{ ticketTokenPairs }.NEXTAUTH_SECRET,WORKER_ENV,EVENT_SERVICE,EXPO_ACCESS_TOKEN,HYPERDRIVE,RECEIPTS_QUEUE, andNOTIFICATION_CHANNEL_DO;STREAM_CHAT_API_SECRETis no longer required.KiloClaw service and runtime
/stream-chat-*HTTP routes.openclaw.jsonbeforeopenclaw doctor, deletingchannels.streamchat, the legacy plugin path, allow entry, and plugin entry.channels["kilo-chat"],/usr/local/lib/node_modules/@kiloclaw/kilo-chat, andkilo-chatin an existing plugin allowlist.additionalMembersfrom bot-created conversations, returns pagination from read actions, and avoids sending resolved approval action blocks through edit payloads.targetBotId=bot:kiloclaw:<sandboxId>, stripstargetBotId, and forwards the webhook body to/plugins/kilo-chat/webhook.image-content-hash.sh,FLY_IMAGE_CONTENT_MODE, local OpenClaw tarball mode, and CI/dev handoff checks.@kilocode/notificationstypes, sendsandboxIdwithoutinstanceId, and log ticket-error counts as warnings.Backwards compatibility:
/api/kiloclaw/chat-credentials,/api/platform/stream-chat-credentials,/api/platform/send-chat-message, or stored Stream Chat credentials must migrate to Kilo Chat.doctor; Kilo Chat is added without creatingplugins.allowwhen it was absent, preserving permissive plugin loading.plugins.allowconfigs must includekilo-chat; this code appends it when the allowlist already exists.FLY_IMAGE_CONTENT_MODEdefaults to production. Local-image dev flows need exactly oneopenclaw-build/openclaw-*.tgzor an explicit production/local mode.instanceId; it is compatible with the updated shared binding becausesandboxIdis now the lifecycle identifier. MissingNOTIFICATIONSstill no-ops.KILOCLAW_SANDBOX_IDandKILOCHAT_BASE_URL; workerKILO_CHATcleanup andNOTIFICATIONSremain optional/failure-tolerant.targetBotIdis used only for routing, then stripped; plugin-side validation still accepts historicalmessage.createdpayloads without atypefield.message,conversation,hasMore,nextCursor) and no longer allow bot-createdadditionalMembers.Dev, deployment, and local tooling
Verification
Visual Changes
Reviewer Notes