export type WsOutEvent = | { room_id: string; project_id?: undefined | null; event: WsEventPayload; error?: undefined | null } | { room_id?: undefined | null; project_id: string; event: WsEventPayload; error?: undefined | null } | { room_id?: undefined | null; project_id?: undefined | null; error: string }; export type WsEventPayload = | { type: 'room_message'; data: RoomMessagePayload } | { type: 'project_event'; data: ProjectEventPayload } | { type: 'ai_stream_chunk'; data: AiStreamChunkPayload }; export type RoomMessagePayload = { id: string; room_id: string; sender_type: string; sender_id?: string | null; thread_id?: string | null; content: string; content_type: string; send_at: string; seq: number; display_name?: string | null; }; export type ProjectEventPayload = { event_type: string; project_id: string; room_id?: string | null; category_id?: string | null; message_id?: string | null; seq?: number | null; timestamp: string; }; export type AiStreamChunkPayload = { message_id: string; room_id: string; content: string; done: boolean; error?: string | null; }; export type RoomWsStatus = 'idle' | 'connecting' | 'open' | 'closing' | 'closed' | 'error'; export function isRoomMessageEvent( event: WsOutEvent, ): event is Extract { return 'event' in event && !('error' in event) && event.event?.type === 'room_message'; } export function isAiStreamChunkEvent( event: WsOutEvent, ): event is Extract { return 'event' in event && !('error' in event) && event.event?.type === 'ai_stream_chunk'; } export function isProjectEvent( event: WsOutEvent, ): event is Extract { return 'event' in event && !('error' in event) && event.event?.type === 'project_event'; } export type { RoomResponse, RoomCategoryResponse, RoomMessageResponse, RoomMessageListResponse, RoomMemberResponse, RoomThreadResponse, UserInfo, ReactionItem, ReactionListData, SearchResultData, EditHistoryEntry, AiConfigData, NotificationData, NotificationListData, MentionData, MentionListData, SubscribeData, MessageEditHistoryResponse, } from './ws-protocol';