OrkaJS
Orka.JS

React Components

Pre-built UI components for agents

A collection of production-ready React components for building AI-powered interfaces. Includes chat UIs, streaming text displays, agent status indicators, and more. All components are fully customizable with Tailwind CSS and support both light and dark modes.

Installation

Install the package along with its peer dependencies. The components are built with React 18+ and use Tailwind CSS for styling.

# ─────────────────────────────────────────────────────────────────────────────
# Install @orka-js/react and its peer dependencies
# ─────────────────────────────────────────────────────────────────────────────
 
npm install @orka-js/react
 
# Or with pnpm
pnpm add @orka-js/react
 
# Peer dependencies (if not already installed):
# - react >= 18.0.0
# - react-dom >= 18.0.0
# - tailwindcss >= 3.0.0 (for styling)

Available Components

AgentChat

Full-featured chat interface with message history, streaming, and file uploads

StreamingText

Display streaming LLM responses with typing animation

AgentStatus

Show agent connection status and activity indicators

ToolCallDisplay

Visualize tool calls and their results in real-time

ThinkingIndicator

Animated indicator while agent is processing

AgentChat Component

The main chat component that handles the entire conversation flow. It connects to your agent API, manages message history, and displays streaming responses.

ChatPage.tsx
// ─────────────────────────────────────────────────────────────────────────────
// AgentChat - Full-featured chat interface
//
// This component provides:
// - Message input with send button
// - Message history display (user + assistant messages)
// - Real-time streaming of agent responses
// - File upload support (images, documents)
// - Automatic scroll to latest message
// - Loading states and error handling
// ─────────────────────────────────────────────────────────────────────────────
 
import { AgentChat } from '@orka-js/react';
 
export default function ChatPage() {
return (
<AgentChat
// ─── Required Props ────────────────────────────────────────────────────
 
// URL of your agent API endpoint
// This should be the endpoint that accepts POST requests with { message: string }
agentUrl="http://localhost:3000/api/agent"
 
// ─── Streaming Configuration ───────────────────────────────────────────
 
// Enable real-time streaming of responses (recommended)
// When true, responses appear token by token as they're generated
streaming={true}
 
// ─── UI Customization ──────────────────────────────────────────────────
 
// Placeholder text shown in the input field
placeholder="Ask me anything..."
 
// Title shown at the top of the chat
title="AI Assistant"
 
// Welcome message shown when chat is empty
welcomeMessage="Hello! How can I help you today?"
 
// ─── Styling ───────────────────────────────────────────────────────────
 
// Custom CSS classes for the container
className="h-[600px] rounded-xl border shadow-lg"
 
// Theme preset: 'light' | 'dark' | 'system'
theme="system"
 
// ─── Event Handlers ────────────────────────────────────────────────────
 
// Called when a message is sent
onMessageSent={(message) => {
console.log('User sent:', message);
}}
 
// Called when agent responds
onResponse={(response) => {
console.log('Agent replied:', response);
}}
 
// Called on errors
onError={(error) => {
console.error('Chat error:', error);
}}
/>
);
}

StreamingText Component

A component that displays text as it streams from the LLM, with a smooth typing animation effect.

CustomChatUI.tsx
// ─────────────────────────────────────────────────────────────────────────────
// StreamingText - Display streaming LLM responses
//
// Use this component when you want to build a custom UI but still want
// the smooth streaming text effect. It handles:
// - Token-by-token display with typing animation
// - Markdown rendering (optional)
// - Code syntax highlighting (optional)
// ─────────────────────────────────────────────────────────────────────────────
 
import { StreamingText, useAgentStream } from '@orka-js/react';
 
export default function CustomChatUI() {
// useAgentStream hook manages the streaming connection
const {
stream, // Function to start streaming
text, // Current accumulated text
isStreaming, // Whether currently receiving tokens
error, // Any error that occurred
reset, // Reset the stream state
} = useAgentStream({
url: 'http://localhost:3000/api/agent',
});
 
const handleSubmit = async (message: string) => {
// Start streaming the response
await stream({ message });
};
 
return (
<div className="p-4">
{/* Your custom input UI */}
<input
type="text"
onKeyDown={(e) => {
if (e.key === 'Enter') {
handleSubmit(e.currentTarget.value);
e.currentTarget.value = '';
}
}}
placeholder="Type a message..."
className="w-full p-2 border rounded"
/>
 
{/* StreamingText displays the response with animation */}
<div className="mt-4 p-4 bg-gray-50 rounded-lg">
<StreamingText
// The text to display (from useAgentStream hook)
text={text}
 
// Show typing animation while streaming
animate={isStreaming}
 
// Render markdown (headers, lists, code blocks, etc.)
markdown={true}
 
// Highlight code blocks with syntax highlighting
syntaxHighlight={true}
 
// Typing speed in milliseconds per character
typingSpeed={20}
 
// Custom styling
className="prose dark:prose-invert"
/>
</div>
 
{/* Loading indicator */}
{isStreaming && (
<div className="mt-2 text-sm text-gray-500">
Agent is thinking...
</div>
)}
</div>
);
}

ToolCallDisplay

Visualize tool calls and their results as they happen during agent execution.

AgentWithTools.tsx
// ─────────────────────────────────────────────────────────────────────────────
// ToolCallDisplay - Visualize tool executions
//
// When your agent calls tools (functions), this component displays:
// - Which tool is being called
// - The arguments passed to the tool
// - The result returned by the tool
// - Execution time and status
// ─────────────────────────────────────────────────────────────────────────────
 
import { ToolCallDisplay, useAgentStream } from '@orka-js/react';
 
export default function AgentWithTools() {
const { stream, text, toolCalls, isStreaming } = useAgentStream({
url: 'http://localhost:3000/api/agent',
});
 
return (
<div className="space-y-4">
{/* Display each tool call as it happens */}
{toolCalls.map((toolCall, index) => (
<ToolCallDisplay
key={index}
 
// Tool call data from the stream
toolCall={toolCall}
 
// Visual style: 'compact' | 'expanded' | 'minimal'
variant="expanded"
 
// Show the arguments passed to the tool
showArguments={true}
 
// Show the result returned by the tool
showResult={true}
 
// Show execution time
showDuration={true}
 
// Custom icons for different tools
icons={{
searchProducts: '🔍',
sendEmail: '📧',
createTicket: '🎫',
}}
 
// Styling
className="border rounded-lg p-3"
/>
))}
 
{/* Agent's final response */}
<div className="p-4 bg-blue-50 rounded-lg">
<StreamingText text={text} animate={isStreaming} />
</div>
</div>
);
}

Custom Styling

All components accept className props and can be styled with Tailwind CSS. You can also use the theme prop for quick customization.

ThemedChat.tsx
// ─────────────────────────────────────────────────────────────────────────────
// Custom Theming
//
// All components support extensive customization through:
// 1. className props (Tailwind CSS)
// 2. theme prop (preset themes)
// 3. Custom CSS variables
// 4. Render props for full control
// ─────────────────────────────────────────────────────────────────────────────
 
import { AgentChat, createTheme } from '@orka-js/react';
 
// Create a custom theme
const myTheme = createTheme({
// Colors
colors: {
primary: '#6366f1', // Indigo
primaryHover: '#4f46e5',
background: '#ffffff',
backgroundSecondary: '#f9fafb',
text: '#111827',
textSecondary: '#6b7280',
border: '#e5e7eb',
userBubble: '#6366f1', // User message background
assistantBubble: '#f3f4f6', // Assistant message background
},
 
// Border radius
borderRadius: {
small: '0.375rem',
medium: '0.5rem',
large: '1rem',
bubble: '1.25rem',
},
 
// Fonts
fonts: {
body: 'Inter, system-ui, sans-serif',
mono: 'JetBrains Mono, monospace',
},
 
// Spacing
spacing: {
messagePadding: '1rem',
inputPadding: '0.75rem',
},
});
 
export default function ThemedChat() {
return (
<AgentChat
agentUrl="http://localhost:3000/api/agent"
theme={myTheme}
 
// Or use className for quick overrides
className="
[--orka-primary:#6366f1]
[--orka-radius:1rem]
"
 
// Custom render props for full control
renderMessage={({ message, isUser }) => (
<div className={`p-3 rounded-xl ${isUser ? 'bg-indigo-500 text-white' : 'bg-gray-100'}`}>
{message.content}
</div>
)}
 
renderInput={({ value, onChange, onSubmit }) => (
<div className="flex gap-2">
<input
value={value}
onChange={(e) => onChange(e.target.value)}
className="flex-1 p-3 border rounded-xl"
/>
<button
onClick={onSubmit}
className="px-6 py-3 bg-indigo-500 text-white rounded-xl"
>
Send
</button>
</div>
)}
/>
);
}

React Hooks

The package also exports hooks for building custom UIs while handling the agent communication logic.

hooks.tsx
// ─────────────────────────────────────────────────────────────────────────────
// React Hooks for Custom UIs
//
// If you want full control over your UI, use these hooks to handle
// the agent communication while building your own components.
// ─────────────────────────────────────────────────────────────────────────────
 
import {
useAgentStream, // Stream responses from agent
useAgentChat, // Full chat state management
useAgentStatus, // Connection status
useToolCalls, // Track tool executions
} from '@orka-js/react';
 
// ─── useAgentChat - Full chat state management ───────────────────────────────
 
function MyCustomChat() {
const {
messages, // Array of all messages [{ role, content, timestamp }]
sendMessage, // Function to send a message
isLoading, // Whether waiting for response
error, // Any error that occurred
clearHistory, // Clear all messages
regenerate, // Regenerate last response
} = useAgentChat({
url: 'http://localhost:3000/api/agent',
streaming: true,
 
// Optional: persist messages to localStorage
persistKey: 'my-chat-history',
 
// Optional: initial messages
initialMessages: [
{ role: 'assistant', content: 'Hello! How can I help?' }
],
});
 
return (
<div>
{messages.map((msg, i) => (
<div key={i} className={msg.role === 'user' ? 'text-right' : 'text-left'}>
{msg.content}
</div>
))}
 
<input
onKeyDown={(e) => {
if (e.key === 'Enter' && !isLoading) {
sendMessage(e.currentTarget.value);
e.currentTarget.value = '';
}
}}
/>
</div>
);
}
 
// ─── useAgentStatus - Monitor connection status ──────────────────────────────
 
function StatusIndicator() {
const {
status, // 'connected' | 'disconnected' | 'error'
latency, // Last response latency in ms
reconnect, // Function to reconnect
} = useAgentStatus({
url: 'http://localhost:3000/api/agent',
pingInterval: 30000, // Check connection every 30s
});
 
return (
<div className="flex items-center gap-2">
<div className={`w-2 h-2 rounded-full ${
status === 'connected' ? 'bg-green-500' :
status === 'error' ? 'bg-red-500' : 'bg-yellow-500'
}`} />
<span>{status}</span>
{latency && <span className="text-xs text-gray-500">{latency}ms</span>}
</div>
);
}

Knowledge Graph Visualization

OrkaKnowledgeGraph renders the entities and relations extracted by KGMemory (@orka-js/memory-store) as an interactive React Flow diagram. Nodes are color-coded by entity type; edges show the relation predicate. Accepts either a live KGMemory instance or raw arrays.

PERSON
ORGANIZATION
LOCATION
CONCEPT
PRODUCT
EVENT
npm install @orka-js/react @orka-js/memory-store

Live KGMemory instance

KnowledgeGraphView.tsx
import { useState, useEffect } from 'react'
import { OrkaKnowledgeGraph } from '@orka-js/react'
import { KGMemory } from '@orka-js/memory-store'
import { OpenAIAdapter } from '@orka-js/openai'
 
const llm = new OpenAIAdapter({ apiKey: process.env.OPENAI_API_KEY! })
const memory = new KGMemory({ llm })
 
export default function KnowledgeGraphView() {
const [refreshKey, setRefreshKey] = useState(0)
 
const sendMessage = async (text: string) => {
await memory.addMessage({ role: 'user', content: text })
const reply = await llm.generate(text)
await memory.addMessage({ role: 'assistant', content: reply })
setRefreshKey(k => k + 1) // trigger re-render
}
 
return (
<div>
<button onClick={() => sendMessage('Alice works at Acme Corp in Paris')}>
Send message
</button>
<OrkaKnowledgeGraph
memory={memory}
refreshKey={refreshKey}
theme="dark"
height={500}
onNodeClick={(name, entity) => console.log('Clicked:', name, entity)}
/>
</div>
)
}

Raw data

StaticKnowledgeGraph.tsx
import { OrkaKnowledgeGraph } from '@orka-js/react'
 
export default function StaticKnowledgeGraph() {
return (
<OrkaKnowledgeGraph
entities={[
{ name: 'Alice', type: 'PERSON' },
{ name: 'Acme Corp', type: 'ORGANIZATION' },
{ name: 'Paris', type: 'LOCATION' },
]}
relations={[
{ subject: 'Alice', predicate: 'works at', object: 'Acme Corp' },
{ subject: 'Acme Corp', predicate: 'located in', object: 'Paris' },
]}
theme="dark"
height={400}
/>
)
}

Props

PropTypeDescription
memoryKGMemoryLikeLive KGMemory — re-renders on refreshKey change
entitiesKGEntity[]Raw entity array (if memory not provided)
relationsKGRelation[]Raw relation array
refreshKeynumber | stringIncrement to force re-render
onNodeClick(name, entity) => voidClick handler on entity nodes
theme'light' | 'dark'Color theme (default: 'dark')
widthnumber | stringWidth (default: '100%')
heightnumber | stringHeight (default: 500)

Styling Tips

  • All components use CSS variables that you can override with Tailwind's arbitrary values
  • Use the `theme` prop for quick color scheme changes
  • Render props give you full control over every part of the UI
  • The hooks are perfect for building completely custom interfaces