smithery/azure-samples

add-message-handler

Add a handler for a new WebSocket message type

Installation

$ npx skills add smithery/azure-samples --skill add-message-handler

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery/azure-samples.

npx skills add smithery/azure-samples

Browse all from smithery/azure-samples

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 3,695 B
  • docs SUMMARY.md 73 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

Add Message Handler Skill

Add handlers for new WebSocket message types in the frontend.

Message Envelope Structure

interface MessageEnvelope {
  type: string;           // Message type identifier
  sender: string;         // "Assistant" | "User" | "System"
  payload: object;        // Actual message content
  ts: string;             // ISO 8601 timestamp
  session_id: string;     // Session identifier
  topic?: string;         // Optional routing topic
}

Steps

1. Define Message Type

Add to message handler switch in hooks/useWebSocket.js or App.jsx:

const handleMessage = useCallback((event) => {
  const envelope = JSON.parse(event.data);

  switch (envelope.type) {
    // ... existing cases ...

    case 'my_new_type':
      handleMyNewType(envelope.payload);
      break;

    default:
      console.log('Unknown message type:', envelope.type);
  }
}, []);

2. Create Handler Function

const handleMyNewType = useCallback((payload) => {
  // Extract data from payload
  const { field1, field2 } = payload;

  // Update state
  setMyState(prev => ({
    ...prev,
    field1,
    field2,
  }));

  // Optional: trigger side effects
  if (field1) {
    onFieldUpdate?.(field1);
  }
}, [onFieldUpdate]);

3. Add State if Needed

const [myState, setMyState] = useState({
  field1: null,
  field2: null,
});

Common Message Types

Type Payload Handler Action
assistant_streaming { content, streaming } Append to message buffer
assistant { content } Finalize message
event { eventtype, eventdata } Route to event handler
tool_start { toolname, toolcall_id } Show tool indicator
tool_end { tool_name, result, error } Hide indicator, log result
audio_data { data, sample_rate } Send to AudioWorklet

Example: Tool Progress Handler

// State
const [activeTools, setActiveTools] = useState(new Map());

// Handler
const handleToolProgress = useCallback((envelope) => {
  const { tool_name, tool_call_id, pct } = envelope.payload;

  setActiveTools(prev => {
    const next = new Map(prev);
    if (envelope.type === 'tool_start') {
      next.set(tool_call_id, { name: tool_name, progress: 0 });
    } else if (envelope.type === 'tool_progress') {
      const tool = next.get(tool_call_id);
      if (tool) next.set(tool_call_id, { ...tool, progress: pct });
    } else if (envelope.type === 'tool_end') {
      next.delete(tool_call_id);
    }
    return next;
  });
}, []);

// In switch
case 'tool_start':
case 'tool_progress':
case 'tool_end':
  handleToolProgress(envelope);
  break;

Example: Event Handler with Routing

const handleEventMessage = useCallback((payload) => {
  const { event_type, event_data } = payload;

  switch (event_type) {
    case 'agent_change':
      setActiveAgent(event_data.active_agent_label);
      break;
    case 'session_updated':
      setSession(prev => ({ ...prev, ...event_data }));
      break;
    case 'call_connected':
      setCallStatus('connected');
      break;
    default:
      console.log('Unhandled event:', event_type);
  }
}, []);

Sending Messages

// Text message envelope
const sendTextMessage = (text) => {
  socket.send(JSON.stringify({
    type: 'user_message',
    sender: 'User',
    payload: { text },
    ts: new Date().toISOString(),
    session_id: sessionId,
  }));
};

// Binary audio data (no envelope)
const sendAudioData = (pcmSamples) => {
  socket.send(pcmSamples.buffer);
};