fix(desktop): require session ids for scoped gateway events (#42178)
* fix(desktop): require session ids for scoped gateway events Drop unscoped stream, tool, and subagent events in the desktop renderer so async activity cannot attach to whichever chat is currently focused. * fix(desktop): preserve unscoped session info events Keep session.info out of the scoped-event drop list so global desktop runtime broadcasts still initialize UI state before a session is active.
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { gatewayEventRequiresSessionId } from './gateway-events'
|
||||
|
||||
describe('gateway event routing', () => {
|
||||
it('requires explicit session ids for async session-scoped events', () => {
|
||||
expect(gatewayEventRequiresSessionId('message.delta')).toBe(true)
|
||||
expect(gatewayEventRequiresSessionId('tool.start')).toBe(true)
|
||||
expect(gatewayEventRequiresSessionId('subagent.progress')).toBe(true)
|
||||
expect(gatewayEventRequiresSessionId('approval.request')).toBe(true)
|
||||
})
|
||||
|
||||
it('allows global events to remain unscoped', () => {
|
||||
expect(gatewayEventRequiresSessionId('gateway.ready')).toBe(false)
|
||||
expect(gatewayEventRequiresSessionId('preview.restart.progress')).toBe(false)
|
||||
expect(gatewayEventRequiresSessionId('session.info')).toBe(false)
|
||||
expect(gatewayEventRequiresSessionId(undefined)).toBe(false)
|
||||
})
|
||||
})
|
||||
@@ -7,10 +7,39 @@ interface RpcEventLike {
|
||||
type?: string
|
||||
}
|
||||
|
||||
const SESSION_SCOPED_EVENT_TYPES = new Set([
|
||||
'approval.request',
|
||||
'clarify.request',
|
||||
'error',
|
||||
'message.complete',
|
||||
'message.delta',
|
||||
'message.start',
|
||||
'reasoning.available',
|
||||
'reasoning.delta',
|
||||
'secret.request',
|
||||
'status.update',
|
||||
'subagent.complete',
|
||||
'subagent.progress',
|
||||
'subagent.spawn_requested',
|
||||
'subagent.start',
|
||||
'subagent.thinking',
|
||||
'subagent.tool',
|
||||
'sudo.request',
|
||||
'thinking.delta'
|
||||
])
|
||||
|
||||
function asRecord(payload: unknown): Record<string, unknown> {
|
||||
return payload && typeof payload === 'object' ? (payload as Record<string, unknown>) : {}
|
||||
}
|
||||
|
||||
export function gatewayEventRequiresSessionId(eventType: string | undefined): boolean {
|
||||
if (!eventType) {
|
||||
return false
|
||||
}
|
||||
|
||||
return SESSION_SCOPED_EVENT_TYPES.has(eventType) || eventType.startsWith('tool.')
|
||||
}
|
||||
|
||||
export function gatewayEventCompletedFileDiff(event: RpcEventLike): boolean {
|
||||
if (event.type !== 'tool.complete') {
|
||||
return false
|
||||
|
||||
Reference in New Issue
Block a user