Skip to content

WebSocket API

The WebSocket API provides real-time communication capabilities for the Daisy system. It handles various events including message streaming, research updates, and system notifications.

Connection

Establishing Connection

typescript
import { io } from 'socket.io-client';

const socket = io('wss://your-daisy-server.com', {
  auth: {
    token: 'your_jwt_token',
  },
});

Events

Message Response Events

typescript
// Listen for message chunks
socket.on(
  'daisy.event.message-response',
  (data: {
    threadId: string;
    content: string;
    artifact?: string;
    messageId: string;
    name: string;
    type: 'ai' | 'tool';
    toolCalls?: string[];
    toolName?: string;
  }) => {
    console.log('Received message chunk:', data);
  },
);

// Message completion event
socket.on(
  'daisy.event.message-response-finished',
  (data: { threadId: string }) => {
    console.log('Message stream completed for thread:', data.threadId);
  },
);

Research Events

typescript
// Research progress updates
socket.on(
  'daisy.event.deep-research-response',
  (data: { threadId: string; content: string; langgraphNode: string }) => {
    console.log('Research update:', data);
  },
);

// Research completion
socket.on(
  'daisy.event.deep-research-response-finished',
  (data: { threadId: string }) => {
    console.log('Research completed for thread:', data.threadId);
  },
);

Thread Events

typescript
// Thread title updates
socket.on(
  'daisy.event.thread-title-updated',
  (data: { threadId: string; title: string }) => {
    console.log('Thread title updated:', data);
  },
);

Usage Examples

Message Streaming

typescript
// Example component handling message streaming
class ChatComponent {
  private messageBuffer = '';

  constructor() {
    this.setupWebSocket();
  }

  private setupWebSocket() {
    socket.on('daisy.event.message-response', (data) => {
      this.handleMessageChunk(data);
    });

    socket.on('daisy.event.message-response-finished', (data) => {
      this.handleMessageComplete(data);
    });
  }

  private handleMessageChunk(data: {
    content: string;
    type: 'ai' | 'tool';
    // ... other properties
  }) {
    if (data.type === 'ai') {
      this.messageBuffer += data.content;
      this.updateUI();
    } else if (data.type === 'tool') {
      this.handleToolResponse(data);
    }
  }

  private handleMessageComplete(data: { threadId: string }) {
    this.finalizeMessage(this.messageBuffer);
    this.messageBuffer = '';
  }
}

Research Progress Tracking

typescript
class ResearchComponent {
  private researchStates: Record<
    string,
    {
      status: 'in_progress' | 'completed';
      content: string;
      currentNode: string;
    }
  > = {};

  constructor() {
    this.setupResearchEvents();
  }

  private setupResearchEvents() {
    socket.on('daisy.event.deep-research-response', (data) => {
      this.updateResearchProgress(data);
    });

    socket.on('daisy.event.deep-research-response-finished', (data) => {
      this.completeResearch(data.threadId);
    });
  }

  private updateResearchProgress(data: {
    threadId: string;
    content: string;
    langgraphNode: string;
  }) {
    this.researchStates[data.threadId] = {
      status: 'in_progress',
      content: data.content,
      currentNode: data.langgraphNode,
    };
    this.updateUI();
  }
}

Error Handling

Connection Errors

typescript
socket.on('connect_error', (error) => {
  console.error('WebSocket connection error:', error);
  // Implement reconnection logic
});

socket.on('disconnect', (reason) => {
  console.log('Disconnected:', reason);
  if (reason === 'io server disconnect') {
    // Disconnected by server
    socket.connect();
  }
});

Message Handling Errors

typescript
socket.on('error', (error) => {
  console.error('WebSocket error:', error);
  // Handle error appropriately
});

// Implement timeout handling
const messageTimeout = setTimeout(() => {
  console.error('Message response timeout');
  // Handle timeout
}, 30000);

socket.on('daisy.event.message-response-finished', () => {
  clearTimeout(messageTimeout);
});

Best Practices

1. Connection Management

  • Implement reconnection strategy
  • Handle connection timeouts
  • Monitor connection state
  • Clean up listeners

2. Message Processing

  • Buffer message chunks
  • Handle out-of-order messages
  • Implement timeout handling
  • Clean up resources

3. Error Recovery

  • Implement exponential backoff
  • Handle partial messages
  • Maintain message order
  • Cache important states

Performance Considerations

1. Message Handling

typescript
// Batch UI updates
let updateTimeout: NodeJS.Timeout;

function handleMessageChunk(content: string) {
  buffer += content;

  clearTimeout(updateTimeout);
  updateTimeout = setTimeout(() => {
    updateUI(buffer);
  }, 100);
}

2. Resource Management

typescript
// Clean up resources on component unmount
class Component {
  cleanup() {
    socket.off('daisy.event.message-response');
    socket.off('daisy.event.message-response-finished');
    clearTimeout(updateTimeout);
    buffer = '';
  }
}

3. Connection Optimization

typescript
const socket = io('wss://your-daisy-server.com', {
  reconnection: true,
  reconnectionDelay: 1000,
  reconnectionDelayMax: 5000,
  reconnectionAttempts: 5,
});

Security Considerations

1. Authentication

typescript
socket.on('connect', () => {
  socket.emit('authenticate', { token: getAuthToken() });
});

socket.on('unauthorized', (error) => {
  console.error('Authentication failed:', error);
  // Handle authentication failure
});

2. Data Validation

typescript
function validateMessageData(data: any): boolean {
  return (
    data &&
    typeof data.threadId === 'string' &&
    typeof data.content === 'string'
  );
}

socket.on('daisy.event.message-response', (data) => {
  if (!validateMessageData(data)) {
    console.error('Invalid message data received');
    return;
  }
  // Process message
});

3. Connection Security

  • Use secure WebSocket (WSS)
  • Implement message encryption
  • Validate origin
  • Monitor connections

Monitoring

Connection Metrics

  • Connection status
  • Reconnection attempts
  • Message latency
  • Error rates

Performance Metrics

  • Message processing time
  • UI update frequency
  • Memory usage
  • Event queue size

Error Tracking

typescript
let errorCount = 0;
const errorThreshold = 5;

socket.on('error', (error) => {
  errorCount++;
  logError(error);

  if (errorCount >= errorThreshold) {
    // Implement circuit breaker
    socket.disconnect();
    // Notify user/system
  }
});

Released under the MIT License.