fix(chat): isolate WS chat events by channel and session key

Add sessionKey to AgentEvent and filter in chat UI so events from
Telegram, cron, and other channels don't leak into WS chat page.
This commit is contained in:
viettranx committed 2026-03-25 13:40:54 +07:00
1 parent 5b614da90e
commit f0b5b61c8e
5 files changed
+20 -4

No files matched your search

+1
View File
@@ -34,6 +34,7 @@ func (l *Loop) runLoop(ctx context.Context, req RunRequest) (*RunResult, error)
event.UserID = req.UserID
event.Channel = req.Channel
event.ChatID = req.ChatID
event.SessionKey = req.SessionKey
event.TenantID = l.tenantID
l.emit(event)
}
+1
View File
@@ -29,6 +29,7 @@ func (l *Loop) Run(ctx context.Context, req RunRequest) (*RunResult, error) {
event.UserID = req.UserID
event.Channel = req.Channel
event.ChatID = req.ChatID
event.SessionKey = req.SessionKey
event.TenantID = store.TenantIDFromContext(ctx)
l.emit(event)
}
+5 -4
View File
@@ -160,10 +160,11 @@ type AgentEvent struct {
TeamTaskID string `json:"teamTaskId,omitempty"`
ParentAgentID string `json:"parentAgentId,omitempty"`
// Routing context (helps WS clients filter by user/channel)
UserID string `json:"userId,omitempty"`
Channel string `json:"channel,omitempty"`
ChatID string `json:"chatId,omitempty"`
// Routing context (helps WS clients filter by user/channel/session)
UserID string `json:"userId,omitempty"`
Channel string `json:"channel,omitempty"`
ChatID string `json:"chatId,omitempty"`
SessionKey string `json:"sessionKey,omitempty"`
// TenantID scopes this event to a specific tenant for filtering (not serialized).
TenantID uuid.UUID `json:"-"`
@@ -34,6 +34,8 @@ export function useChatMessages(sessionKey: string, agentId: string) {
const toolStreamRef = useRef<ToolStreamEntry[]>([]);
const agentIdRef = useRef(agentId);
agentIdRef.current = agentId;
const sessionKeyRef = useRef(sessionKey);
sessionKeyRef.current = sessionKey;
const activityRef = useRef<RunActivity | null>(null);
const blockRepliesRef = useRef<ChatMessage[]>([]);
const rafPendingRef = useRef(false);
@@ -155,6 +157,15 @@ export function useChatMessages(sessionKey: string, agentId: string) {
const event = payload as AgentEventPayload;
if (!event) return;
// Only process events from WS channel targeting the active session.
// Delegations/announces (runKind set) are allowed regardless of channel.
if (event.channel && event.channel !== "ws" && !event.runKind) {
return;
}
if (event.sessionKey && event.sessionKey !== sessionKeyRef.current) {
return;
}
// Capture run.started when we are expecting a run for this agent,
// OR when an announce run starts (leader summarising team results).
if (event.type === "run.started" && event.agentId === agentIdRef.current) {
+2
View File
@@ -52,6 +52,8 @@ export interface AgentEventPayload {
agentId: string;
runId: string;
runKind?: string; // "delegation" | "announce" — omitted for user-initiated runs
channel?: string; // "ws", "telegram", "cron", etc.
sessionKey?: string; // session this event belongs to
payload?: {
content?: string;
name?: string;