HUMA-0.1 Agent API
Event-driven agent architecture with client-defined tools and flexible context.
Overview
HUMA-0.1 is an event-driven agent architecture that enables real-time AI interactions through WebSocket connections. Agents are defined client-side with personality, instructions, and custom tools, then instantiated server-side for processing.
Key Concepts
Define personality, instructions, and tools in your client code
Define any tools you need - executed by your client, results sent back
Send any JSON context - chat history, game state, user data, etc.
Real-time bidirectional communication via WebSocket
Architecture
Events + Tool Results
Tool Calls + Status
Event Flow
- 1Create agent via REST API with personality, instructions, and tool definitions
- 2Connect to agent via WebSocket with agent ID
- 3Send events with context (chat history, user data, game state, etc.)
- 4Receive tool-call events → Execute tool in your client → Send result back
- 5Agent continues processing with tool results until complete
Authentication
All API endpoints require API key authentication. API keys are associated with users.
1. Create a User
POST /api/users
{
"email": "dev@example.com",
"name": "Developer"
}
// Response:
{
"id": "clx123...",
"email": "dev@example.com",
"name": "Developer",
"createdAt": "2025-11-29T..."
}2. Create an API Key
POST /api/users/{userId}/api-keys
{
"name": "Production Key"
}
// Response:
{
"id": "clx456...",
"key": "ak_Xk9mP2qR4tV6wY8zA1bC3dE5fG7hJ9kL", // Save this! Only shown once
"keyPreview": "...9kL",
"name": "Production Key"
}Using the API Key
Include the X-API-Key header in HTTP requests and apiKey query param for WebSocket:
// HTTP Requests
fetch('/api/agents', {
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'ak_your_api_key'
}
});
// WebSocket Connection
const socket = io('wss://api.humalike.tech', {
query: {
agentId: 'your-agent-id',
apiKey: 'ak_your_api_key'
}
});Agent Class Definition
An Agent Class defines WHO the agent is and WHAT it can do. This is provided client-side when creating an agent instance.
Structure
interface AgentClassDefinition {
// Unique name for this agent class
className: string;
// Agent's personality - defines WHO they are
personality: string;
// Instructions for behavior - defines WHAT they do
instructions: string;
// Available tools the agent can use
tools: ToolDefinition[];
}Example: Coach Alex
const COACH_ALEX_CLASS = {
className: 'Coach Alex',
personality: `You are Coach Alex, an enthusiastic and supportive fitness coach.
You're always positive and encouraging, but also practical and knowledgeable.
You speak in a friendly, conversational tone and use fitness-related metaphors.
You genuinely care about your clients' progress and wellbeing.`,
instructions: `Your role is to help users with their fitness journey:
- Provide workout advice and exercise recommendations
- Give nutrition tips when asked
- Motivate users to stay consistent
- Answer fitness-related questions
- Be supportive but realistic about expectations
When you want to send a message to the user, use the send_message tool.
Always be encouraging and helpful.`,
tools: [
{
name: 'send_message',
description: 'Send a message to the user in the chat',
parameters: [
{
name: 'message',
type: 'string',
description: 'The message content to send to the user',
required: true,
},
],
},
],
};Creating an Agent Instance
Create an agent instance via the REST API. The agent's personality, instructions, and tools are stored in the metadata field.
Endpoint
POST /api/agentsRequest Body
{
"name": "Coach Alex Instance",
"description": "HUMA-0.1 Coach Alex fitness coach",
"agentType": "HUMA-0.1",
"metadata": {
"className": "Coach Alex",
"personality": "You are Coach Alex...",
"instructions": "Your role is to help users...",
"tools": [
{
"name": "send_message",
"description": "Send a message to the user",
"parameters": [
{
"name": "message",
"type": "string",
"description": "The message content",
"required": true
}
]
}
]
}
}Response
{
"id": "clx1abc123def456",
"name": "Coach Alex Instance",
"description": "HUMA-0.1 Coach Alex fitness coach",
"agentType": "HUMA-0.1",
"status": "active",
"metadata": { ... },
"createdAt": "2025-11-29T10:30:00.000Z",
"updatedAt": "2025-11-29T10:30:00.000Z"
}WebSocket Connection
Connect to the agent via WebSocket to send events and receive tool calls.
Connect
import { io } from 'socket.io-client';
const socket = io('wss://api.humalike.tech', {
query: {
agentId: 'clx1abc123def456',
apiKey: 'ak_your_api_key'
},
transports: ['websocket']
});
socket.on('connect', () => {
console.log('Connected to agent');
});Initial Status
Upon connection, the server emits an initial status event:
socket.on('event', (data) => {
// { type: 'status', status: 'idle' }
});Event Types
Client → Server Events
All client events are sent via the message channel with type huma-0.1-event:
socket.emit('message', {
type: 'huma-0.1-event',
content: {
// Event content here
}
});HUMA-0.1 Event Structure
interface Huma01Event {
// Event name/type (e.g., "new-message", "session-start")
name: string;
// New context to replace the current agent context
context: Record;
// Human-readable description of what happened
description: string;
} Example: New Message Event
socket.emit('message', {
type: 'huma-0.1-event',
content: {
name: 'new-message',
context: {
chatHistory: [
{ id: '1', author: 'User', content: 'Hello!', timestamp: '...' }
],
user: { name: 'Alice', fitnessLevel: 'beginner' }
},
description: 'User "Alice" sent new message: "Hello!"'
}
});Tool Result Event
Sent after executing a tool requested by the agent:
socket.emit('message', {
type: 'huma-0.1-event',
content: {
type: 'tool-result',
toolCallId: 'tc_abc123',
success: true,
result: 'Message sent to user'
}
});Server → Client Events
All server events are received on the event channel:
| Event Type | Description | Fields |
|---|---|---|
| status | Agent processing state | status: 'idle' | 'thinking' |
| tool-call | Request client to execute a tool | toolCallId, toolName, arguments |
| error | Error occurred | message, code? |
Example: Tool Call Event
{
"type": "tool-call",
"toolCallId": "tc_abc123",
"toolName": "send_message",
"arguments": {
"message": "Hey! Great to hear from you! Ready to crush today's workout?"
}
}Tool System
Tools are defined in the agent metadata and executed by your client. This allows maximum flexibility for your application.
Tool Definition
interface ToolDefinition {
name: string;
description: string;
parameters: ToolParameter[];
}
interface ToolParameter {
name: string;
type: 'string' | 'number' | 'boolean' | 'object' | 'array';
description: string;
required?: boolean;
}Tool Execution Flow
- 1Server sends
tool-callevent with tool name and arguments - 2Client executes the tool (e.g., displays message, plays sound, updates UI)
- 3Client sends
tool-resultevent with success/failure and result
Common Tool Examples
{
name: 'send_message',
description: 'Send a message to the user in the chat',
parameters: [
{ name: 'message', type: 'string', description: 'The message content', required: true }
]
}{
name: 'play_card',
description: 'Play a card from hand',
parameters: [
{ name: 'cardId', type: 'string', description: 'Card to play', required: true },
{ name: 'target', type: 'string', description: 'Target player', required: false }
]
}{
name: 'send_notification',
description: 'Send a push notification',
parameters: [
{ name: 'title', type: 'string', description: 'Notification title', required: true },
{ name: 'body', type: 'string', description: 'Notification body', required: true }
]
}Complete Example
Overview
This example demonstrates the complete HUMA-0.1 workflow: creating a fitness coach agent with client-defined personality, instructions, and tools.
What This Code Does
Setup Phase
- Define Agent Class: Personality, instructions, tools (client-side)
- Create Agent: POST to /api/agents with metadata
- Connect WebSocket: Real-time connection with agent ID
Communication Phase
- Send Events: User messages with full context
- Handle Tool Calls: Execute tools, send results back
- Track Status: Monitor agent thinking/idle state
The Code
import { io } from 'socket.io-client';
const API = 'https://api.humalike.tech';
const API_KEY = 'ak_your_api_key';
// 1. Define Agent Class (client-side)
const COACH_ALEX_CLASS = {
className: 'Coach Alex',
personality: `You are Coach Alex, an enthusiastic fitness coach.
You're positive, encouraging, and knowledgeable about fitness.`,
instructions: `Help users with their fitness journey:
- Provide workout advice and motivation
- Answer fitness-related questions
- Use the send_message tool to respond`,
tools: [
{
name: 'send_message',
description: 'Send a message to the user in the chat',
parameters: [
{ name: 'message', type: 'string', description: 'Message content', required: true }
]
}
]
};
// Track chat history
const chatHistory = [];
async function main() {
// 2. Create Agent Instance
const agent = await fetch(`${API}/api/agents`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': API_KEY },
body: JSON.stringify({
name: 'Coach Alex Instance',
agentType: 'HUMA-0.1',
metadata: COACH_ALEX_CLASS
})
}).then(r => r.json());
console.log('Created agent:', agent.id);
// 3. Connect WebSocket
const socket = io(API, {
query: { agentId: agent.id, apiKey: API_KEY },
transports: ['websocket']
});
// 4. Handle Server Events
socket.on('event', (data) => {
switch (data.type) {
case 'status':
console.log(`Agent status: ${data.status}`);
break;
case 'tool-call':
handleToolCall(socket, data);
break;
case 'error':
console.error(`Error: ${data.message}`);
break;
}
});
// 5. Send Initial Event on Connect
socket.on('connect', () => {
console.log('Connected to agent');
sendUserMessage(socket, 'Hey! Ready for today\'s workout!', 'Alice');
});
}
// Handle tool calls from agent
function handleToolCall(socket, data) {
if (data.toolName === 'send_message') {
const message = data.arguments.message;
// Display message in UI
console.log(`Coach Alex: ${message}`);
// Add to chat history
chatHistory.push({
id: crypto.randomUUID(),
author: 'Coach Alex',
content: message,
timestamp: new Date().toISOString()
});
// Send success result back to server
socket.emit('message', {
type: 'huma-0.1-event',
content: {
type: 'tool-result',
toolCallId: data.toolCallId,
success: true,
result: 'Message displayed'
}
});
}
}
// Send user message to agent
function sendUserMessage(socket, content, userName) {
// Add to chat history
chatHistory.push({
id: crypto.randomUUID(),
author: userName,
content,
timestamp: new Date().toISOString()
});
// Send event to agent with full context
socket.emit('message', {
type: 'huma-0.1-event',
content: {
name: 'new-message',
context: {
chatHistory: chatHistory.slice(-50), // Last 50 messages
user: { name: userName }
},
description: `User "${userName}" sent: "${content}"`
}
});
}
main();Best Practices
Context Design
- Keep context focused and relevant
- Include recent history (last 50 messages recommended)
- Add user metadata for personalization
- Replace context fully on each event
Event Descriptions
- Be specific about what happened
- Include relevant details (who, what, when)
- Use natural language the AI can understand
Tool Design
- Keep tools focused on single actions
- Provide clear descriptions
- Mark required parameters explicitly
- Handle errors gracefully on client side
Error Handling
- Always listen for error events
- Implement reconnection logic
- Handle tool execution failures
- Log errors for debugging