Skip to main content

Overview

CometChat’s “Bring Your Own Agent” (BYOA) feature allows you to integrate your custom AI agent with CometChat’s full-stack platform. This approach provides:
  • Complete Control: Host and manage your own agent logic
  • Flexibility: Use any AI provider or custom model
  • Self-Service: Configure everything through the CometChat dashboard
  • Production-Ready UI: CometChat handles chat interface, moderation, and analytics
  • Security: Secure communication via headers and authentication

How It Works

  1. Host Your Agent: Deploy an AG-UI compatible agent on your infrastructure
  2. Configure in CometChat: Add agent details in the CometChat dashboard
  3. Secure Connection: Set up authentication headers
  4. Seamless Integration: CometChat sends AG-UI messages to your agent and streams responses

Key Benefits

  • No Infrastructure Headaches: CometChat provides the UI, moderation, and monitoring
  • Model Agnostic: Works with OpenAI, Anthropic, Mastra, LangGraph, or custom models
  • Multi-Agent Support: Connect multiple specialized agents
  • Real-Time Streaming: Token-by-token response streaming
  • Tool Integration: Execute frontend tools from your agent

Building an AG-UI Compatible Agent

Core Requirements

An AG-UI compatible agent must:
  1. Accept POST requests with RunAgentInput body
  2. Return streaming responses as Server-Sent Events (SSE)
  3. Emit AG-UI events in the correct sequence
  4. Handle errors gracefully with RUN_ERROR events

RunAgentInput Interface

Every AG-UI agent receives this input:
interface RunAgentInput {
  threadId: string           // ID of the conversation thread
  runId: string             // ID of the current run
  state: any                // Current state of the agent
  messages: Message[]       // Array of messages in conversation
  tools: Tool[]            // Array of tools available to agent
  context: Context[]       // Array of context objects
  forwardedProps: any      // Additional properties
}

Tool Interface

interface Tool {
  name: string
  description: string
  parameters: {
    type: "object"
    properties: Record<string, any>
    required?: string[]
  }
}

Basic Agent Implementation Pattern

// 1. Accept POST request with RunAgentInput
app.post('/agent', async (req, res) => {
  const input: RunAgentInput = req.body;
  
  // 2. Set up Server-Sent Events
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');
  
  // 3. Create event encoder
  const encoder = new EventEncoder();
  
  try {
    // 4. Emit RUN_STARTED
    res.write(encoder.encode({
      type: EventType.RUN_STARTED,
      threadId: input.threadId,
      runId: input.runId
    }));
    
    // 5. Process request and stream response
    // ... your agent logic here ...
    
    // 6. Emit RUN_FINISHED
    res.write(encoder.encode({
      type: EventType.RUN_FINISHED,
      threadId: input.threadId,
      runId: input.runId
    }));
    
    res.end();
    
  } catch (error) {
    // 7. Handle errors with RUN_ERROR
    res.write(encoder.encode({
      type: EventType.RUN_ERROR,
      message: error.message
    }));
    res.end();
  }
});