Skip to main content

Agent Integration Patterns

OpsHub NAV offers 4 specialized integration patterns for connecting to the Agent System. Each pattern is optimized for specific use cases, from simple chat interfaces to complex multi-agent workflows.
Quick Start: Most developers should start with CopilotKit for simple chat or AG-UI for complex workflows. Choose SSE for real-time streaming or Workspace Context for ambient intelligence features.

Why 4 Different Patterns?

Different AI-powered features require different communication patterns:
  • CopilotKit: Best for simple, familiar chat interfaces with minimal setup
  • AG-UI Protocol: Designed for complex multi-agent orchestration with shared state
  • SSE Streaming: Optimized for real-time text generation with low latency
  • Workspace Context: Enables context-aware features without explicit user requests
Each pattern has trade-offs in complexity, latency, state management, and bidirectional communication capabilities.

Pattern Comparison

FeatureCopilotKitAG-UISSE StreamingWorkspace Context
Connection TypeWebSocketHTTPServer-Sent EventsHTTP
Bidirectional✅ Yes✅ Yes (polling)❌ No✅ Yes
State ManagementClient-sideShared (Zustand)NoneServer-side
Best ForChat UIMulti-agent workflowsStreaming textContext awareness
ComplexityLowHighLowMedium
LatencyLowMediumLowMedium

Quick Decision Guide

Use this flowchart to choose the right pattern:

Decision Matrix

If You Need…Use This PatternWhy
Quick chat interface for help/Q&ACopilotKitLow complexity, familiar chat UX, React hooks included
Multiple agents collaborating on a taskAG-UIShared state management, multi-agent coordination
Real-time LLM completion streamingSSE StreamingLowest latency for token-by-token display
Context-aware suggestions without user askingWorkspace ContextAutomatic page detection, ambient intelligence
Human-in-loop approval workflowsAG-UIBuilt-in tool execution gates and state persistence
Simple request/response with streamingSSE StreamingMinimal overhead, no state management needed

Pattern 1: CopilotKit (WebSocket)

What It Is

CopilotKit provides a drop-in chat interface with React hooks and UI components, connected via WebSocket for real-time bidirectional communication.

When to Use

✅ Use For

  • Simple chat interfaces
  • Contextual help and assistance
  • Quick Q&A features
  • Real-time collaboration

❌ Avoid For

  • Complex multi-agent orchestration
  • State persistence across sessions
  • Bulk data processing

Key Features

  • React hooks for easy integration (useCopilotChat, useCopilotAction)
  • Pre-built UI components (CopilotPopup, CopilotSidebar)
  • WebSocket connection for real-time updates
  • Low latency bidirectional communication

Quick Example

// app/(app)/help/page.tsx
import { CopilotKit } from "@copilotkit/react-core";
import { CopilotPopup } from "@copilotkit/react-ui";

export default function HelpPage() {
  return (
    <CopilotKit runtimeUrl="/api/copilotkit">
      <div className="content">
        <h1>Need Help?</h1>
        <p>Ask our AI assistant anything!</p>
      </div>
      <CopilotPopup
        instructions="You are a helpful assistant for OpsHub NAV users."
        defaultOpen={true}
      />
    </CopilotKit>
  );
}
API Proxy Required: Create /api/copilotkit/route.ts to proxy requests to the backend with proper authentication.

Learn More

CopilotKit Pattern Details

Complete implementation guide with backend setup, authentication, and advanced features

Pattern 2: AG-UI Protocol

What It Is

AG-UI is a protocol for multi-agent orchestration with shared state management, designed for complex workflows where multiple agents collaborate.

When to Use

✅ Use For

  • Complex agent workflows
  • Multi-agent coordination
  • Shared state across components
  • Tool execution with human-in-the-loop

❌ Avoid For

  • Simple single-message requests
  • Stateless operations
  • Quick prototypes

Key Features

  • Multi-agent state management via Zustand stores
  • Tool execution framework with approval gates
  • Message history persisted across sessions
  • Human-in-the-loop workflows with signals

Quick Example

// components/agent/DataAnalysisWorkflow.tsx
import { useMultiAgentClient } from '@/lib/agent/multi-agent-client';

export function DataAnalysisWorkflow() {
  const client = useMultiAgentClient({
    userId: user.id,
    sessionId: 'analysis-session',
  });

  const runAnalysis = async () => {
    // Step 1: Query agent fetches data
    await client.sendMessage('Fetch portfolio holdings', {
      agent: 'query-agent',
      portfolioId: 'port-123',
    });

    // Step 2: Analysis agent processes
    await client.sendMessage('Calculate risk metrics', {
      agent: 'analysis-agent',
    });

    // Step 3: Validation agent checks
    await client.sendMessage('Validate against ASIC RG94', {
      agent: 'validation-agent',
    });
  };

  return (
    <div>
      <MessageList messages={client.messages} />
      <button onClick={runAnalysis}>Run Multi-Agent Analysis</button>
    </div>
  );
}
Complexity Trade-off: AG-UI requires more setup than CopilotKit but provides fine-grained control over multi-agent workflows.

Learn More

AG-UI Protocol Details

Complete implementation guide with state management, tool execution, and multi-agent coordination

Pattern 3: SSE Streaming (Vercel AI SDK)

What It Is

Server-Sent Events (SSE) provide one-way real-time streaming from server to client, ideal for LLM token-by-token completions.

When to Use

✅ Use For

  • Real-time text streaming
  • Progress updates during long operations
  • Token-by-token completions
  • Simple request/response with streaming

❌ Avoid For

  • Bidirectional communication needs
  • Complex state management
  • Multi-turn conversations

Key Features

  • Lowest latency for streaming text
  • Token-by-token display for LLM responses
  • Progress updates during long-running operations
  • Simple implementation with minimal overhead

Quick Example

// components/StreamingCompletion.tsx
import { useAgentStream } from '@/lib/agent/use-agent-stream';

export function StreamingCompletion() {
  const { messages, isLoading, sendMessage } = useAgentStream({
    sessionId: generateId(),
  });

  return (
    <div>
      <div className="messages">
        {messages.map(msg => (
          <div key={msg.id}>
            <strong>{msg.role}:</strong> {msg.content}
          </div>
        ))}
      </div>

      <form onSubmit={(e) => {
        e.preventDefault();
        sendMessage(e.currentTarget.message.value);
      }}>
        <input name="message" placeholder="Type your message..." />
        <button disabled={isLoading}>Send</button>
      </form>
    </div>
  );
}
One-Way Communication: SSE is server-to-client only. For bidirectional needs, use WebSocket (CopilotKit) or HTTP polling (AG-UI).

Learn More

SSE Streaming Details

Complete implementation guide with event handling, error recovery, and optimization

Pattern 4: Workspace Context Sync

What It Is

Workspace Context Sync provides automatic context detection from the current page, enabling ambient intelligence and proactive suggestions.

When to Use

✅ Use For

  • Automatic context detection
  • Ambient intelligence features
  • Page-aware AI suggestions
  • Proactive insights

❌ Avoid For

  • User-initiated interactions (use other patterns)
  • Scenarios where context is not relevant
  • Simple CRUD operations

Key Features

  • Automatic page detection from URL and state
  • Context-aware suggestions without user prompting
  • Server-side context storage for persistence
  • Proactive insights based on user activity

Quick Example

// app/(app)/data-modeling/page.tsx
import { useWorkspace } from '@/lib/contexts/WorkspaceContext';

export function DataModelingPage() {
  const workspace = useWorkspace();
  const [suggestions, setSuggestions] = useState([]);

  useEffect(() => {
    // Context automatically synced to backend
    workspace.updateContext({
      page: '/data-modeling',
      selectedTables: selectedTables.map(t => t.name),
      currentQuery: queryBuilder.toSQL(),
    });

    // Backend provides context-aware suggestions
    fetchSuggestions().then(setSuggestions);
  }, [selectedTables, queryBuilder]);

  return (
    <div>
      <QueryBuilder />
      <SmartSuggestions suggestions={suggestions} />
    </div>
  );
}
Privacy Consideration: Context sync happens in the background. Ensure users are aware of context collection and provide opt-out options if needed.

Learn More

Workspace Context Details

Complete implementation guide with context detection, privacy controls, and optimization

Authentication & Security

All 4 integration patterns use the same standardized authentication approach for consistency and security.

Standard Authentication Pattern

// lib/api/backend-auth.ts
import { createClient } from '@/lib/supabase/server';

export async function getAuthHeaders(): Promise<HeadersInit> {
  const supabase = await createClient();
  const { data: { session }, error } = await supabase.auth.getSession();

  if (error || !session) {
    throw new Error('Unauthorized: User must be authenticated');
  }

  // CRITICAL: Use session.access_token (JWT), NOT user.id
  return {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${session.access_token}`,
  };
}

URL Configuration Helper

// lib/config/agent-backend-url.ts
export function buildAgentUrl(path: string): string {
  const base = process.env.AGENT_BACKEND_URL;
  if (!base) {
    throw new Error('AGENT_BACKEND_URL not configured');
  }
  return `${base}${path}`;
}

Usage in API Routes

// app/api/agent/*/route.ts
import { buildAgentUrl } from '@/lib/config/agent-backend-url';
import { getAuthHeaders } from '@/lib/api/backend-auth';

export async function POST(request: Request) {
  const authHeaders = await getAuthHeaders();
  const backendUrl = buildAgentUrl('/api/endpoint');

  const response = await fetch(backendUrl, {
    method: 'POST',
    headers: authHeaders,
    body: await request.text(),
  });

  return response;
}

Security Best Practices

  • Use getAuthHeaders() for all backend requests
  • Use buildAgentUrl() for URL construction
  • Keep AGENT_BACKEND_URL server-side only (no NEXT_PUBLIC_)
  • Validate JWT tokens on backend
  • Use Next.js API routes as proxy (never direct browser → backend)
Common Security Mistake: Never use user.id as a Bearer token. Always use session.access_token which is a proper JWT that the backend can validate.

Environment Configuration

# .env.local (server-side only)
AGENT_BACKEND_URL=https://opshub-agent-backend.fly.dev
AGENT_API_KEY=your_api_key

# DEPRECATED (backward compatibility only)
# NEXT_PUBLIC_AGENT_API_URL=...
# NEXT_PUBLIC_AGENT_BACKEND_URL=...
EnvironmentAGENT_BACKEND_URL
Developmenthttp://localhost:8000
Staginghttps://staging-agent.fly.dev
Productionhttps://opshub-agent-backend.fly.dev

Getting Started

Step 1: Choose Your Pattern

Use the Quick Decision Guide to select the right pattern for your use case.

Step 2: Set Up Authentication

Configure environment variables and create helper functions:
# Add to .env.local
AGENT_BACKEND_URL=http://localhost:8000

Step 3: Create API Proxy

All patterns require a Next.js API route to proxy requests:
// app/api/agent/[pattern]/route.ts
import { buildAgentUrl } from '@/lib/config/agent-backend-url';
import { getAuthHeaders } from '@/lib/api/backend-auth';

export async function POST(request: Request) {
  const authHeaders = await getAuthHeaders();
  const backendUrl = buildAgentUrl('/api/pattern-endpoint');

  const response = await fetch(backendUrl, {
    method: 'POST',
    headers: authHeaders,
    body: await request.text(),
  });

  return response;
}

Step 4: Follow Pattern-Specific Guide

CopilotKit Setup

Install dependencies, configure WebSocket, add UI components

AG-UI Setup

Create multi-agent client, set up state management, implement tools

SSE Streaming Setup

Create streaming hook, handle events, implement UI updates

Workspace Context Setup

Set up context provider, implement sync logic, handle context updates

Pattern Selection Examples

Example 1: Help Chat

Requirement: Add a help chatbot to answer user questions Pattern: CopilotKit Why: Simple chat interface, no complex state, familiar UX

Example 2: Data Analysis Workflow

Requirement: Multi-step analysis involving data fetch → calculation → validation → report Pattern: AG-UI Protocol Why: Multiple agents need to coordinate, shared state required, human approval before final report

Example 3: Report Generation

Requirement: Generate a long report with real-time progress updates Pattern: SSE Streaming Why: One-way streaming of progress text, no bidirectional communication needed

Example 4: Smart Query Suggestions

Requirement: Show relevant query suggestions based on current page and data Pattern: Workspace Context Sync Why: Automatic context detection, proactive suggestions without user prompting

Troubleshooting Common Issues

”Unauthorized” Errors

Cause: Using user.id instead of JWT token Fix:
// WRONG ❌
headers: { 'Authorization': `Bearer ${user.id}` }

// CORRECT ✅
const authHeaders = await getAuthHeaders();

“AGENT_BACKEND_URL not configured”

Cause: Missing environment variable Fix:
# Add to .env.local
AGENT_BACKEND_URL=http://localhost:8000

CORS Errors in Browser

Cause: Direct browser → backend requests (bypassing Next.js proxy) Fix: Always use Next.js API routes as proxy
// WRONG ❌
fetch('https://backend.fly.dev/api/chat')

// CORRECT ✅
fetch('/api/agent/chat')  // Proxied through Next.js

WebSocket Connection Fails (CopilotKit)

Cause: WebSocket endpoint not properly configured Fix: Ensure backend WebSocket endpoint matches frontend config
# Backend
@app.websocket("/copilotkit")
async def copilotkit_ws(websocket: WebSocket)
// Frontend
<CopilotKit runtimeUrl="/api/copilotkit">

Summary

Simple Chat

Use CopilotKit
  • Low complexity
  • React hooks included
  • WebSocket real-time

Complex Workflows

Use AG-UI
  • Multi-agent coordination
  • Shared state management
  • Human-in-the-loop

Streaming Text

Use SSE
  • Lowest latency
  • Token-by-token display
  • Simple implementation

Context Awareness

Use Workspace Context
  • Automatic detection
  • Ambient intelligence
  • Proactive insights

Additional Resources

CopilotKit Docs

Official CopilotKit documentation

AG-UI GitHub

AG-UI protocol specification and examples

Vercel AI SDK

Vercel AI SDK for SSE streaming

Last Updated: October 29, 2025 Status: ✅ Production Ready - All patterns fixed and standardized