All files / src/events websocket.events.ts

0% Statements 0/21
0% Branches 0/53
0% Functions 0/1
0% Lines 0/21

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128                                                                                                                                                                                                                                                               
// Copied from userscripts/src/conversation-types.ts to avoid creating a shared package.
// This is a temporary solution until a shared types package is introduced.
export interface Turn {
  id: string;
  role: 'user' | 'model';
  content: string;
  thoughts?: string;
}
 
export interface Conversation {
  id: string;
  title: string;
  model: string;
  turns: Turn[];
}
// End copied content
 
/**
 * Defines the structure for all WebSocket events in the system.
 * This type is duplicated across frontend, backend, and userscripts.
 * Any changes here must be synchronized.
 */
export type WebSocketEvent =
  | { event: 'refresh-ui'; data: { sessionId?: string } }
  | { event: 'update-chat'; data: { requestBody: Conversation } }
  | { event: 'plan-ready'; data: { sessionId: string; sessionInputId: string } }
  | { event: 'external-new-session'; data: Record<string, never> }
  | {
      event: 'system-prompt-update';
      data: { systemPrompt: string };
    }
  | { event: 'session-created'; data: { sessionId: string } }
  | { event: 'llm-input-generated'; data: { prompt: string } }
  | {
      event: 'llm-stream-chunk';
      data: { sessionInputId: string; chunk: string; isFirst: boolean };
    }
  | {
      event: 'llm-thought-chunk';
      data: { sessionInputId: string; chunk: string; isFirst: boolean };
    }
  | {
      event: 'llm-generation-started';
      data: { sessionInputId: string; sessionId: string; isStreaming: boolean };
    }
  | { event: 'llm-generation-in-progress'; data: { sessionInputId: string } }
  | {
      event: 'llm-generation-ended';
      data: { sessionInputId: string; sessionId: string; error?: string };
    }
  | {
      event: 'llm-retry-attempt';
      data: {
        sessionInputId: string;
        sessionId: string;
        attempt: number;
        maxAttempts: number;
      };
    };
export type WebSocketEventName = WebSocketEvent['event'];
 
/**
 * A type guard to check if a parsed JSON object is a valid WebSocketEvent.
 * @param obj The object to check.
 * @returns True if the object is a valid WebSocketEvent, false otherwise.
 */
export function isWebSocketEvent(obj: unknown): obj is WebSocketEvent {
  Iif (typeof obj !== 'object' || obj === null) {
    return false;
  }
  const { event, data } = obj as { event: string; data: unknown };
  Iif (typeof event !== 'string' || typeof data !== 'object') {
    return false;
  }
 
  switch (event) {
    case 'refresh-ui':
      return true; // data can be {} or { sessionId: '...' }
    case 'update-chat':
      return data !== null && 'requestBody' in data;
    case 'plan-ready':
      return data !== null && 'sessionId' in data && 'sessionInputId' in data;
    case 'external-new-session':
      return true; // data is {}
    case 'system-prompt-update':
      return data !== null && 'systemPrompt' in data;
    case 'session-created':
      return data !== null && 'sessionId' in data;
    case 'llm-input-generated':
      return data !== null && 'prompt' in data;
    case 'llm-stream-chunk':
      return (
        data !== null &&
        'sessionInputId' in data &&
        'chunk' in data &&
        'isFirst' in data
      );
    case 'llm-thought-chunk':
      return (
        data !== null &&
        'sessionInputId' in data &&
        'chunk' in data &&
        'isFirst' in data
      );
    case 'llm-generation-started':
      return (
        data !== null &&
        'sessionInputId' in data &&
        'sessionId' in data &&
        'isStreaming' in data
      );
    case 'llm-generation-in-progress':
      return data !== null && 'sessionInputId' in data;
    case 'llm-generation-ended':
      return data !== null && 'sessionInputId' in data && 'sessionId' in data;
    case 'llm-retry-attempt':
      return (
        data !== null &&
        'sessionInputId' in data &&
        'sessionId' in data &&
        'attempt' in data &&
        'maxAttempts' in data
      );
    default:
      return false;
  }
}