OrkaJS
Orka.JS

Serveur Agent & UI

Hébergez des agents avec un playground visuel

Lancez un serveur HTTP production-ready avec une belle UI React pour tester et interagir avec vos agents. Le serveur fournit des endpoints REST API pour chaque agent, support WebSocket pour le streaming temps réel, et un playground visuel pour les tests. Parfait pour démos, développement, outils internes, et même déploiements production.

Installation

Installez le package serveur. Il inclut l'UI React playground bundlée, donc pas de setup frontend supplémentaire nécessaire.

# ─────────────────────────────────────────────────────────────────────────────
# Install @orka-js/server
# The package includes the React playground UI bundled
# ─────────────────────────────────────────────────────────────────────────────
 
npm install @orka-js/server
 
# Or with pnpm
pnpm add @orka-js/server
 
# The server uses Express.js under the hood
# All dependencies are included, no additional setup needed

Fonctionnalités Clés

Playground Visuel

UI React intégrée pour tester les agents avec interface chat

API REST

Endpoints REST auto-générés pour chaque agent enregistré

Streaming WebSocket

Streaming de tokens en temps réel via connexions WebSocket

Authentification

Support intégré pour clés API et authentification JWT

CORS & Sécurité

CORS configurable, rate limiting, et headers de sécurité

Utilisation Basique

Créez un serveur avec un ou plusieurs agents. Chaque agent obtient son propre endpoint API automatiquement.

server.ts
// ─────────────────────────────────────────────────────────────────────────────
// Basic Server Setup
//
// This creates a server with a single agent and starts it on port 3000.
// The playground UI will be available at http://localhost:3000/playground
// ─────────────────────────────────────────────────────────────────────────────
 
import { createOrkaServer } from '@orka-js/server';
import { StreamingToolAgent } from '@orka-js/agent';
import { OpenAIAdapter } from '@orka-js/openai';
 
// ─── Step 1: Create your LLM adapter ─────────────────────────────────────────
 
const llm = new OpenAIAdapter({
apiKey: process.env.OPENAI_API_KEY!,
model: 'gpt-4o', // Use any OpenAI model
});
 
// ─── Step 2: Define your agent's tools ───────────────────────────────────────
 
const searchKnowledgeBase = {
name: 'searchKnowledgeBase',
description: 'Search the company knowledge base for information',
parameters: {
type: 'object',
properties: {
query: { type: 'string', description: 'The search query' },
},
required: ['query'],
},
execute: async ({ query }: { query: string }) => {
// Your search logic here
return { results: ['Result 1', 'Result 2'] };
},
};
 
// ─── Step 3: Create your agent ───────────────────────────────────────────────
 
const supportAgent = new StreamingToolAgent({
// The agent's purpose - guides its behavior
goal: 'Help customers find answers to their questions about our products',
 
// System prompt for additional context
systemPrompt: `You are a helpful customer support agent.
Be friendly, professional, and thorough in your responses.
Always search the knowledge base before answering questions.`,
 
// Tools the agent can use
tools: [searchKnowledgeBase],
}, llm);
 
// ─── Step 4: Create and start the server ─────────────────────────────────────
 
const server = createOrkaServer({
// Register agents with their names
// The name becomes part of the API endpoint: /api/agents/{name}
agents: {
support: supportAgent,
},
}, {
// Server port (default: 3000)
port: 3000,
 
// Automatically open the playground in your browser
openBrowser: true,
 
// Enable CORS for cross-origin requests
cors: true,
});
 
// Start the server
server.start();
 
// Output:
// ┌─────────────────────────────────────────────────────────────┐
// │ OrkaJS Server v1.0.0 │
// │ │
// │ API: http://localhost:3000/api │
// │ Playground: http://localhost:3000/playground │
// │ │
// │ Agents: │
// │ • support POST /api/agents/support │
// │ │
// │ Ready to accept connections │
// └─────────────────────────────────────────────────────────────┘

Serveur Multi-Agents

Enregistrez plusieurs agents avec différentes capacités. L'UI playground vous permet de basculer entre eux.

multi-agent-server.ts
// ─────────────────────────────────────────────────────────────────────────────
// Multi-Agent Server
//
// Register multiple agents with different capabilities.
// Each agent gets its own endpoint and appears in the playground dropdown.
// ─────────────────────────────────────────────────────────────────────────────
 
import { createOrkaServer } from '@orka-js/server';
import { StreamingToolAgent, ReActAgent } from '@orka-js/agent';
import { OpenAIAdapter } from '@orka-js/openai';
import { AnthropicAdapter } from '@orka-js/anthropic';
 
// Different LLMs for different agents
const openai = new OpenAIAdapter({ apiKey: process.env.OPENAI_API_KEY! });
const anthropic = new AnthropicAdapter({ apiKey: process.env.ANTHROPIC_API_KEY! });
 
// ─── Support Agent: Fast responses with GPT-4o ───────────────────────────────
 
const supportAgent = new StreamingToolAgent({
goal: 'Help customers with product questions',
tools: [searchProducts, checkOrderStatus],
}, openai);
 
// ─── Research Agent: Deep analysis with Claude ───────────────────────────────
 
const researchAgent = new ReActAgent({
goal: 'Conduct thorough research and analysis',
tools: [webSearch, summarizeDocument, analyzeData],
maxIterations: 10, // Allow more reasoning steps
}, anthropic);
 
// ─── Sales Agent: Product recommendations ────────────────────────────────────
 
const salesAgent = new StreamingToolAgent({
goal: 'Help customers find the perfect product',
systemPrompt: 'You are a friendly sales assistant. Ask questions to understand customer needs.',
tools: [searchProducts, getProductDetails, checkInventory],
}, openai);
 
// ─── Create server with all agents ───────────────────────────────────────────
 
const server = createOrkaServer({
agents: {
// Each key becomes the agent's endpoint name
support: supportAgent, // POST /api/agents/support
research: researchAgent, // POST /api/agents/research
sales: salesAgent, // POST /api/agents/sales
},
 
// Optional: Add metadata for the playground UI
agentMetadata: {
support: {
displayName: 'Customer Support',
description: 'Get help with orders and products',
icon: '🎧',
},
research: {
displayName: 'Research Assistant',
description: 'Deep analysis and research',
icon: '🔬',
},
sales: {
displayName: 'Sales Assistant',
description: 'Find the perfect product',
icon: '🛒',
},
},
}, {
port: 3000,
cors: true,
});
 
server.start();

Authentification

Protégez vos agents avec authentification par clé API ou JWT. Vous pouvez aussi ajouter des middlewares personnalisés.

secure-server.ts
// ─────────────────────────────────────────────────────────────────────────────
// Authentication & Security
//
// Protect your agents with API keys, JWT tokens, or custom middleware.
// ─────────────────────────────────────────────────────────────────────────────
 
import { createOrkaServer } from '@orka-js/server';
 
const server = createOrkaServer({
agents: { support: supportAgent },
}, {
port: 3000,
 
// ─── API Key Authentication ────────────────────────────────────────────────
// Clients must include: Authorization: Bearer <api-key>
 
auth: {
type: 'api-key',
 
// List of valid API keys
apiKeys: [
process.env.API_KEY_1!,
process.env.API_KEY_2!,
],
 
// Or use a validation function for dynamic keys
validateKey: async (key: string) => {
// Check against your database
const isValid = await db.apiKeys.exists(key);
return isValid;
},
},
 
// ─── JWT Authentication ────────────────────────────────────────────────────
// Clients must include: Authorization: Bearer <jwt-token>
 
// auth: {
// type: 'jwt',
// secret: process.env.JWT_SECRET!,
//
// // Optional: Extract user info from token
// extractUser: (payload) => ({
// id: payload.sub,
// email: payload.email,
// }),
// },
 
// ─── Rate Limiting ─────────────────────────────────────────────────────────
// Prevent abuse by limiting requests per IP/user
 
rateLimit: {
// Maximum requests per window
max: 100,
 
// Time window in milliseconds (1 minute)
windowMs: 60 * 1000,
 
// Custom key generator (default: IP address)
keyGenerator: (req) => req.headers['x-user-id'] || req.ip,
 
// Custom response when rate limited
message: 'Too many requests, please try again later',
},
 
// ─── Custom Middleware ─────────────────────────────────────────────────────
// Add your own Express middleware
 
middleware: [
// Logging middleware
(req, res, next) => {
console.log(`[${new Date().toISOString()}] ${req.method} ${req.path}`);
next();
},
 
// Custom auth middleware
async (req, res, next) => {
const userId = req.headers['x-user-id'];
if (userId) {
req.user = await db.users.findById(userId);
}
next();
},
],
 
// ─── Security Headers ──────────────────────────────────────────────────────
 
security: {
// Enable Helmet.js security headers
helmet: true,
 
// Content Security Policy
csp: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'"],
},
},
},
});
 
server.start();

Configuration du Serveur

Options de configuration complètes pour personnaliser le comportement du serveur.

config.ts
// ─────────────────────────────────────────────────────────────────────────────
// Full Server Configuration
//
// All available options for customizing the server.
// ─────────────────────────────────────────────────────────────────────────────
 
import { createOrkaServer } from '@orka-js/server';
 
const server = createOrkaServer({
agents: { support: supportAgent },
}, {
// ─── Basic Settings ────────────────────────────────────────────────────────
 
port: 3000, // Server port (default: 3000)
host: '0.0.0.0', // Host to bind to (default: localhost)
 
// ─── Playground UI ─────────────────────────────────────────────────────────
 
playground: {
enabled: true, // Enable/disable playground (default: true)
path: '/playground', // URL path for playground
title: 'My Agent Playground', // Custom title
theme: 'dark', // 'light' | 'dark' | 'system'
},
 
// ─── CORS Configuration ────────────────────────────────────────────────────
 
cors: {
origin: ['http://localhost:3001', 'https://myapp.com'],
methods: ['GET', 'POST'],
credentials: true,
},
 
// ─── WebSocket Settings ────────────────────────────────────────────────────
 
websocket: {
enabled: true, // Enable WebSocket support
path: '/ws', // WebSocket endpoint path
pingInterval: 30000, // Keep-alive ping interval (ms)
},
 
// ─── Logging ───────────────────────────────────────────────────────────────
 
logging: {
level: 'info', // 'debug' | 'info' | 'warn' | 'error'
format: 'json', // 'json' | 'pretty'
 
// Log specific events
logRequests: true, // Log incoming requests
logResponses: true, // Log outgoing responses
logToolCalls: true, // Log agent tool executions
},
 
// ─── Request Limits ────────────────────────────────────────────────────────
 
limits: {
maxRequestSize: '10mb', // Maximum request body size
timeout: 120000, // Request timeout in ms (2 minutes)
},
 
// ─── Hooks ─────────────────────────────────────────────────────────────────
 
hooks: {
// Called before each agent request
beforeRequest: async (req, agentName) => {
console.log(`Request to agent: ${agentName}`);
},
 
// Called after each agent response
afterResponse: async (req, res, agentName, duration) => {
console.log(`Agent ${agentName} responded in ${duration}ms`);
},
 
// Called on errors
onError: async (error, req, agentName) => {
console.error(`Error in agent ${agentName}:`, error);
// Send to error tracking service
await errorTracker.capture(error);
},
},
 
// ─── Browser Auto-Open ─────────────────────────────────────────────────────
 
openBrowser: true, // Open playground on start
});
 
// ─── Server Methods ──────────────────────────────────────────────────────────
 
// Start the server
await server.start();
 
// Stop the server gracefully
await server.stop();
 
// Get the Express app instance (for custom routes)
const app = server.getApp();
app.get('/health', (req, res) => res.json({ status: 'ok' }));
 
// Get registered agents
const agents = server.getAgents();
console.log('Registered agents:', Object.keys(agents));

Endpoints API

Le serveur crée automatiquement ces endpoints pour chaque agent :

api-reference.http
# ─────────────────────────────────────────────────────────────────────────────
# Auto-Generated API Endpoints
#
# For each agent registered, the server creates these endpoints:
# ─────────────────────────────────────────────────────────────────────────────
 
# ─── Chat Endpoint (POST) ─────────────────────────────────────────────────────
# Send a message to the agent and get a response
 
POST /api/agents/{agentName}
Content-Type: application/json
 
{
"message": "What products do you have?",
"sessionId": "optional-session-id", # For conversation memory
"stream": false # Set to true for streaming
}
 
# Response (non-streaming):
{
"response": "We have a wide variety of products...",
"toolCalls": [
{ "name": "searchProducts", "args": { "query": "all" }, "result": [...] }
],
"usage": { "promptTokens": 150, "completionTokens": 200 }
}
 
# ─── Streaming Endpoint (POST) ────────────────────────────────────────────────
# Get real-time token streaming via Server-Sent Events
 
POST /api/agents/{agentName}/stream
Content-Type: application/json
 
{
"message": "Tell me about your products"
}
 
# Response: Server-Sent Events stream
data: {"type":"token","content":"We"}
data: {"type":"token","content":" have"}
data: {"type":"tool_start","name":"searchProducts","args":{}}
data: {"type":"tool_end","name":"searchProducts","result":[...]}
data: {"type":"token","content":" many"}
data: {"type":"done","usage":{"promptTokens":150,"completionTokens":200}}
 
# ─── Agent Info (GET) ─────────────────────────────────────────────────────────
# Get information about a specific agent
 
GET /api/agents/{agentName}/info
 
# Response:
{
"name": "support",
"goal": "Help customers with product questions",
"tools": ["searchProducts", "checkOrderStatus"],
"metadata": { "displayName": "Customer Support", "icon": "🎧" }
}
 
# ─── List Agents (GET) ────────────────────────────────────────────────────────
# Get a list of all registered agents
 
GET /api/agents
 
# Response:
{
"agents": [
{ "name": "support", "displayName": "Customer Support" },
{ "name": "sales", "displayName": "Sales Assistant" }
]
}
 
# ─── Health Check (GET) ───────────────────────────────────────────────────────
# Check if the server is running
 
GET /api/health
 
# Response:
{ "status": "ok", "uptime": 3600, "agents": 2 }

Conseils de Déploiement

  • Utilisez des variables d'environnement pour les clés API et secrets
  • Activez le rate limiting en production pour prévenir les abus
  • Configurez les origines CORS correctes pour vos domaines frontend
  • Utilisez l'endpoint health pour les health checks du load balancer
  • Envisagez de désactiver le playground en production (playground.enabled: false)