Skip to main content

Implementation Patterns

UI Integration

Create responsive UI that reflects collaboration state using React:
import React, { useState, useEffect } from 'react';

// Main collaboration component
const CollaborationManager = ({ collaborationManager }) => {
    const [activeCollaborations, setActiveCollaborations] = useState(new Map());

    useEffect(() => {
        const handleCollaborationStarted = (event) => {
            const { agents, id } = event.detail;
            setActiveCollaborations(prev => new Map(prev.set(id, {
                id,
                agents,
                phase: 'started',
                agentStatuses: new Map(agents.map(agent => [agent.handle, 'pending']))
            })));
        };

        const handleAgentStatusUpdated = (event) => {
            const { collaborationId, agentHandle, status } = event.detail;
            setActiveCollaborations(prev => {
                const updated = new Map(prev);
                const collaboration = updated.get(collaborationId);
                if (collaboration) {
                    collaboration.agentStatuses.set(agentHandle, status);
                    updated.set(collaborationId, { ...collaboration });
                }
                return updated;
            });
        };

        const handleCollaborationCompleted = (event) => {
            const { id } = event.detail;
            setActiveCollaborations(prev => {
                const updated = new Map(prev);
                updated.delete(id);
                return updated;
            });
        };

        // Add event listeners
        document.addEventListener('collaboration_started', handleCollaborationStarted);
        document.addEventListener('agent_status_updated', handleAgentStatusUpdated);
        document.addEventListener('collaboration_completed', handleCollaborationCompleted);

        return () => {
            document.removeEventListener('collaboration_started', handleCollaborationStarted);
            document.removeEventListener('agent_status_updated', handleAgentStatusUpdated);
            document.removeEventListener('collaboration_completed', handleCollaborationCompleted);
        };
    }, []);

    return (
        <div className="collaboration-container">
            {Array.from(activeCollaborations.values()).map(collaboration => (
                <CollaborationStatus 
                    key={collaboration.id}
                    collaboration={collaboration}
                />
            ))}
        </div>
    );
};

// Individual collaboration status component
const CollaborationStatus = ({ collaboration }) => {
    const { id, agents, phase, agentStatuses } = collaboration;

    return (
        <div className="collaboration-status" data-collaboration={id}>
            <div className="collaboration-header">
                <span className="collaboration-phase">{phase}</span>
                <span className="collaboration-id">ID: {id}</span>
            </div>
            <div className="participating-agents">
                {agents.map(agent => (
                    <AgentStatus 
                        key={agent.handle}
                        agent={agent}
                        status={agentStatuses.get(agent.handle) || 'pending'}
                    />
                ))}
            </div>
        </div>
    );
};

// Individual agent status component
const AgentStatus = ({ agent, status }) => {
    const statusClass = `agent-status-indicator ${status}`;
    
    return (
        <div className="agent-status" data-agent={agent.handle}>
            <span className="agent-name">@{agent.handle}</span>
            <span className={statusClass}>{status}</span>
        </div>
    );
};

Message Filtering

Filter messages during collaboration for better UX using React hooks:
import React, { useState, useEffect, useCallback } from 'react';

const MessageManager = ({ sseClient }) => {
    const [messages, setMessages] = useState([]);
    const [messageQueue, setMessageQueue] = useState([]);
    const [activeCollaborations, setActiveCollaborations] = useState(new Set());

    const isCollaborationActive = useCallback(() => {
        return activeCollaborations.size > 0;
    }, [activeCollaborations]);

    const isIndividualAgentResponse = useCallback((message) => {
        return message.collaborationId && !message.isUnifiedResponse;
    }, []);

    const handleMessage = useCallback((message) => {
        // During collaboration, queue individual agent messages
        if (isCollaborationActive() && isIndividualAgentResponse(message)) {
            setMessageQueue(prev => [...prev, message]);
            return; // Don't display yet
        }
        
        // Display unified response or non-collaboration messages immediately
        setMessages(prev => [...prev, message]);
    }, [isCollaborationActive, isIndividualAgentResponse]);

    const handleCollaborationComplete = useCallback((collaborationId) => {
        setMessageQueue(prev => {
            const collaborationMessages = prev.filter(
                msg => msg.collaborationId === collaborationId
            );
            
            // Display individual responses or clear queue based on whether unified response was provided
            const hasUnifiedResponse = collaborationMessages.some(msg => msg.isUnifiedResponse);
            
            if (!hasUnifiedResponse) {
                // Display individual responses
                setMessages(prevMessages => [...prevMessages, ...collaborationMessages]);
            }
            
            // Remove processed messages from queue
            return prev.filter(msg => msg.collaborationId !== collaborationId);
        });
        
        setActiveCollaborations(prev => {
            const updated = new Set(prev);
            updated.delete(collaborationId);
            return updated;
        });
    }, []);

    useEffect(() => {
        const handleCollaborationStarted = (event) => {
            const { id } = event.detail;
            setActiveCollaborations(prev => new Set(prev.add(id)));
        };

        const handleCollaborationCompleted = (event) => {
            const { id } = event.detail;
            handleCollaborationComplete(id);
        };

        document.addEventListener('collaboration_started', handleCollaborationStarted);
        document.addEventListener('collaboration_completed', handleCollaborationCompleted);

        return () => {
            document.removeEventListener('collaboration_started', handleCollaborationStarted);
            document.removeEventListener('collaboration_completed', handleCollaborationCompleted);
        };
    }, [handleCollaborationComplete]);

    return (
        <div className="message-container">
            {messages.map((message, index) => (
                <MessageComponent key={index} message={message} />
            ))}
        </div>
    );
};

const MessageComponent = ({ message }) => {
    return (
        <div className={`message ${message.role}`}>
            <div className="message-content">{message.content}</div>
            {message.collaborationId && (
                <div className="collaboration-badge">
                    Collaboration: {message.collaborationId}
                </div>
            )}
        </div>
    );
};

Best Practices

1. Performance Optimization

  • Event Filtering: Only process collaboration events when needed
  • State Cleanup: Remove completed collaborations from memory
  • Batch Updates: Group UI updates for better performance

2. User Experience

  • Real-time Feedback: Show collaboration progress and participating agents
  • Error Recovery: Provide clear error messages and retry options
  • Loading States: Display appropriate loading indicators during planning and execution

3. Scalability

  • Connection Management: Implement proper reconnection logic
  • Memory Management: Clean up completed collaboration state
  • Rate Limiting: Handle API rate limits gracefully

4. Error Handling

  • Graceful Degradation: Fall back to individual responses on collaboration failure
  • User Communication: Provide clear feedback on collaboration status
  • Logging: Log collaboration events for debugging and monitoring

5. Testing Collaboration

Test collaboration scenarios:
// Test collaboration detection
const testMessage = {
    content: [{
        type: "text", 
        text: "@product @engineering work on auth feature"
    }]
};

// Test error scenarios
const invalidMessage = {
    content: [{
        type: "text",
        text: "@nonexistent @invalid collaborate"
    }]
};

// Monitor events during testing
function testCollaborationFlow() {
    const events = [];
    
    document.addEventListener('collaboration_started', (e) => {
        events.push({ type: 'started', data: e.detail });
    });
    
    document.addEventListener('collaboration_completed', (e) => {
        events.push({ type: 'completed', data: e.detail });
        console.log('Collaboration test results:', events);
    });
}

Conclusion

This SSE-based collaboration system provides a robust foundation for building multi-agent workflows. By building upon the existing API Integration Guide, you can implement sophisticated collaboration features that enhance user productivity through seamless agent-to-agent communication. The 12 collaboration events provide complete visibility into the collaboration lifecycle, enabling you to build responsive, user-friendly interfaces that keep users informed throughout the collaborative process.
I