Building Context-Aware Chat
Overview
Context-aware chat is the core feature of the Cyborg SDK - it allows the AI to understand what page the user is on, what data they're viewing, and what actions are available. This creates smarter, more relevant responses.
How Context-Aware Chat Works
User is viewing: Product Detail Page
↓ (Component calls useCyborg hook)
↓ (Context about page is sent to chat)
↓ (Backend retrieves relevant docs for this product)
↓ (AI generates response considering current context)
↓ (User gets response tailored to current page)The useCyborg Hook
The useCyborg hook allows any component to provide context about the current page or session.
Basic Usage
import { useCyborg } from '@cyborg-sdk/react'
function ProductPage({ productId }) {
const product = useProduct(productId)
useCyborg({
context: {
page: 'product',
productId: product.id,
productName: product.name,
category: product.category,
inStock: product.inStock
},
instructions: `Help users understand ${product.name}. Answer questions about features, pricing, and availability.`,
suggestedPrompts: [
`Tell me about ${product.name}`,
'What are the key features?',
'Is this product right for me?'
]
})
return (
<div>
<h1>{product.name}</h1>
{/* Product details */}
</div>
)
}Context Data
Provide any key-value data about the current page or user state:
useCyborg({
context: {
// Page information
page: 'dashboard',
section: 'analytics',
// User information
userId: currentUser.id,
userRole: currentUser.role,
subscriptionTier: 'premium',
// Business data
stats: {
totalRevenue: stats.revenue,
activeUsers: stats.users,
conversionRate: stats.conversion
},
// UI state
selectedDateRange: 'last-30-days',
activeFilters: ['category', 'region']
}
})Instructions
Guide the AI's behavior with context-specific instructions:
useCyborg({
context: { page: 'checkout', step: 'payment' },
instructions: `
The user is completing checkout.
Help with:
- Payment method questions
- Shipping options
- Promo code issues
Don't suggest going back to browse products.
Focus on completing the purchase.
`
})Practical Examples
Example 1: Product Page
import { useCyborg } from '@cyborg-sdk/react'
function ProductDetailPage({ productId }) {
const product = fetchProduct(productId)
useCyborg({
context: {
page: 'product-detail',
productId,
productName: product.name,
price: product.price,
category: product.category,
inStock: product.inStock,
features: product.features,
rating: product.averageRating
},
instructions: `
Help users understand ${product.name}.
Highlight key features: ${product.features.join(', ')}.
Current price is $${product.price}.
${product.inStock ? 'Product is in stock.' : 'Product is out of stock - suggest alternatives.'}
`,
suggestedPrompts: [
`Tell me about ${product.name}`,
'What are the key features?',
'How does it compare to alternatives?',
'Is this good for beginners?'
]
})
return <ProductDetails product={product} />
}Example 2: Dashboard Page
import { useCyborg } from '@cyborg-sdk/react'
function DashboardPage() {
const { stats, recentData } = useDashboard()
useCyborg({
context: {
page: 'dashboard',
metrics: {
totalRevenue: stats.revenue,
activeUsers: stats.users,
conversionRate: stats.conversion,
monthOverMonth: stats.growth
},
recentActivity: recentData.slice(0, 5)
},
instructions: `
Help the user understand their dashboard metrics.
Key stats:
- Revenue: $${stats.revenue.toLocaleString()}
- Active users: ${stats.users}
- Conversion rate: ${stats.conversion}%
- Growth: ${stats.growth > 0 ? '+' : ''}${stats.growth}% MoM
Provide actionable insights based on the data.
`,
suggestedPrompts: [
'How is my business doing?',
'What should I focus on?',
'Explain my conversion rate',
'How can I improve growth?'
]
})
return <Dashboard stats={stats} />
}Example 3: Support Page with Tools
import { useCyborg } from '@cyborg-sdk/react'
function SupportPage({ user, tickets }) {
useCyborg({
context: {
page: 'support',
userId: user.id,
openTickets: tickets.filter(t => t.status === 'open').length,
subscriptionTier: user.tier
},
instructions: `
You're helping a ${user.tier} customer with support.
They have ${tickets.filter(t => t.status === 'open').length} open tickets.
Be helpful and offer to create tickets for issues.
`,
tools: [{
name: 'createTicket',
description: 'Create a support ticket for the user',
parameters: {
type: 'object',
properties: {
title: { type: 'string', description: 'Brief description of the issue' },
priority: { type: 'string', enum: ['low', 'medium', 'high'] },
category: { type: 'string', enum: ['billing', 'technical', 'general'] }
},
required: ['title', 'priority']
},
handler: async ({ title, priority, category }) => {
const ticket = await api.createTicket({
userId: user.id,
title,
priority,
category
})
return {
success: true,
ticketId: ticket.id,
message: `Created ticket #${ticket.id}`
}
}
}],
suggestedPrompts: [
'I need help with billing',
'Report a bug',
'How do I upgrade my plan?'
]
})
return <SupportDashboard tickets={tickets} />
}Example 4: Settings Page
import { useCyborg } from '@cyborg-sdk/react'
function SettingsPage() {
const { user, settings } = useUserSettings()
useCyborg({
context: {
page: 'settings',
userId: user.id,
email: user.email,
plan: user.plan,
currentSettings: {
notifications: settings.notifications,
theme: settings.theme,
language: settings.language
}
},
instructions: `
Help the user with account settings.
Current plan: ${user.plan}
Email notifications: ${settings.notifications ? 'enabled' : 'disabled'}
Theme: ${settings.theme}
`,
tools: [{
name: 'updateSettings',
description: 'Update user settings',
parameters: {
type: 'object',
properties: {
notifications: { type: 'boolean', description: 'Enable email notifications' },
theme: { type: 'string', enum: ['light', 'dark', 'auto'] }
}
},
handler: async (newSettings) => {
await api.updateSettings(user.id, newSettings)
return { success: true, message: 'Settings updated' }
}
}],
suggestedPrompts: [
'Change my notification settings',
'Switch to dark mode',
'How do I upgrade my plan?'
]
})
return <SettingsForm settings={settings} />
}Best Practices
1. Call useCyborg at the Page Level
Good: Call at the page/route level
// ✅ Call once per page
function ProductPage() {
useCyborg({ context: { page: 'product', ... } })
return <ProductContent />
}Avoid: Calling in deeply nested components
// ❌ Avoid calling in deeply nested components
function DeepChild() {
useCyborg({ ... }) // Too deep, harder to manage
}2. Keep Context Focused
Good: Include relevant information
useCyborg({
context: {
page: 'products',
productId: '123',
productName: 'Laptop',
price: 999,
inStock: true
}
})Avoid: Including everything
// ❌ Too much data
useCyborg({
context: {
...allProductData, // Entire product object
...allUIState, // All component state
...allAnalytics // All tracking data
}
})3. Write Clear Instructions
// Good: Clear, actionable instructions
useCyborg({
instructions: `
Help users find the right laptop.
Key factors: budget, use case (gaming/work/casual), portability.
Recommend products from our catalog based on their needs.
`
})
// Avoid: Vague instructions
useCyborg({
instructions: 'Help with products'
})4. Use Dynamic Context
Update context when data changes:
function DashboardPage() {
const { stats, selectedPeriod } = useDashboard()
// Context updates when stats or period changes
useCyborg({
context: {
page: 'dashboard',
period: selectedPeriod,
stats: {
revenue: stats.revenue,
users: stats.users
}
},
instructions: `Showing ${selectedPeriod} data. Revenue: $${stats.revenue}`
})
return <Dashboard />
}Multiple Components
Multiple components can contribute context simultaneously:
// Layout.tsx - Global context
function Layout({ children }) {
const user = useAuth()
useCyborg({
context: {
app: 'MyApp',
userId: user?.id,
userRole: user?.role
},
instructions: 'You are an assistant for MyApp.'
})
return <div>{children}</div>
}
// ProductPage.tsx - Page-specific context
function ProductPage({ product }) {
useCyborg({
context: {
page: 'product',
productId: product.id,
productName: product.name
},
instructions: `Currently viewing ${product.name}.`
})
return <ProductDetails product={product} />
}
// Both contexts are merged automatically
// AI sees: app, userId, userRole, page, productId, productName
// Instructions are concatenatedCommon Questions
Q: How much context can I send?
A: There's no hard limit, but keep it reasonable. Aim for 100-1000 characters. Excessive data may slow down responses.
Q: Does context persist between pages?
A: No, context is component-specific. When components unmount, their context is automatically cleaned up. Call useCyborg() on each page.
Q: Can I send sensitive data in context?
A: Be careful with PII and secrets. Context is sent to the server. See Security Best Practices.
Q: What if I don't call useCyborg?
A: Chat still works! It just won't have page context, so responses will be more generic.
Next Steps
- Review Security Best Practices - Understand what data to share
- Tool Calling Guide - Enable AI to execute actions
- useCyborg API Reference - Full API documentation
- Conversation History - Enable persistent chats