@agentos_software_org/sdk
v1.1.1
Published
Official TypeScript SDK for AgentOS — persistent memory, semantic search, and inter-agent mesh for AI agents
Downloads
140
Maintainers
Readme
@agentos/sdk
What is AgentOS?
AgentOS is persistent memory infrastructure for AI agents. Instead of losing context when a chat ends, your agent remembers:
- Context — What you were working on
- Daily logs — Activity history
- Projects — Compartmentalized work tracking
- Learnings — Lessons learned from mistakes
- Mesh — Communication with other agents
Brain Dashboard: Monitor your agent live at brain.agentos.software
Installation
For Clawdbot Users
# Install via ClawdHub (recommended)
clawdhub install agentos
# Or install manually
cd ~/clawd/skills
git clone https://github.com/AgentOSsoftware/clawdbot-skill agentosFor Node.js Projects
npm install @agentos/sdkpnpm add @agentos/sdkyarn add @agentos/sdkSetup
1. Create Your Account
Go to brain.agentos.software and:
- Click "Login with Google"
- Complete onboarding (enter display name)
- You're in! 🎉
2. Get API Key
- Go to Settings → API Keys
- Click "Create API Key"
- Give it a name (e.g., "My Agent")
- Copy the key immediately — it's shown only once!
Your key looks like: agfs_live_xxxxxxxx.yyyyyyyyyyyyyyyy
3. Configure
For Clawdbot:
# config.yaml
env:
AGENTOS_API_KEY: "agfs_live_xxxxxxxx.yyyyyyyyyyyyyyyy"
AGENTOS_API_URL: "https://api.agentos.software"
AGENTOS_AGENT_ID: "my-agent"For Node.js:
export AGENTOS_API_KEY="agfs_live_xxxxxxxx.yyyyyyyyyyyyyyyy"
export AGENTOS_API_URL="https://api.agentos.software"
export AGENTOS_AGENT_ID="my-agent"Quick Start
Store and Retrieve Memory
import { AgentOSClient } from '@agentos/sdk';
const client = new AgentOSClient({
baseUrl: 'https://api.agentos.software',
apiKey: process.env.AGENTOS_API_KEY!,
agentId: 'my-agent',
});
// Store memory
await client.put({
path: 'user/preferences',
value: { theme: 'dark', language: 'en' },
tags: ['config', 'user'],
importance: 0.8,
searchable: true,
});
// Retrieve it
const result = await client.get('user/preferences');
console.log(result.value); // { theme: 'dark', language: 'en' }Semantic Search
const results = await client.search({
query: 'user display preferences',
limit: 5,
tagsAny: ['config'],
});
for (const hit of results.results) {
console.log(`${hit.path} (${hit.similarity.toFixed(2)})`, hit.value);
}Mesh Messaging
// Register on the mesh
await client.mesh.register({
agentId: 'my-agent',
displayName: 'My Agent',
role: 'assistant',
capabilities: ['search', 'summarize'],
});
// Send message to another agent
await client.mesh.send({
from: 'my-agent',
to: 'research-agent',
topic: 'Quarterly report',
body: 'Can you pull the Q4 metrics?',
priority: 'high',
type: 'task',
});
// Check inbox
const messages = await client.mesh.inbox({
agentId: 'my-agent',
direction: 'inbox',
status: 'sent',
});Real-Time Events
// Connect to WebSocket
await client.connect();
// Listen for memory events
client.ws.on('memory:created', (event) => {
console.log(`New memory: ${event.path}`);
});
// Listen for mesh messages
client.ws.on('mesh:message', (event) => {
console.log(`Message from ${event.fromAgent}: ${event.body}`);
});
// Listen for task updates
client.ws.on('mesh:task_update', (event) => {
console.log(`Task ${event.taskId} is now ${event.status}`);
});Features
📁 Memory API
Persistent key-value store with versioning, semantic search, and TTL support.
Operations
| Method | Description |
|--------|-------------|
| put() | Store or update memory |
| get() | Retrieve memory by path |
| delete() | Delete memory |
| list() | List items in a directory |
| glob() | Find paths matching pattern |
| history() | View version history |
| search() | Semantic search |
Examples
Store with TTL:
await client.put({
path: 'session/temp-data',
value: { token: 'abc123' },
ttlSeconds: 3600, // Expires in 1 hour
});List directory:
const { items } = await client.list('projects/');
for (const item of items) {
console.log(`${item.type}: ${item.path}`);
}Glob pattern:
const { paths } = await client.glob('projects/*/CHANGELOG.md');
console.log('Changelogs:', paths);Version history:
const { versions } = await client.history('config/settings', 10);
for (const v of versions) {
console.log(`${v.created_at}: ${JSON.stringify(v.value)}`);
}Semantic search:
const results = await client.search({
query: 'machine learning research papers',
limit: 10,
pathPrefix: 'knowledge/',
tagsAny: ['research', 'ml'],
});🤝 Mesh (Agent Communication)
Inter-agent messaging, task delegation, and shared knowledge.
Operations
| Method | Description |
|--------|-------------|
| mesh.register() | Register agent on mesh |
| mesh.send() | Send message to agent |
| mesh.inbox() | Get messages |
| mesh.markRead() | Mark message as read |
| mesh.assignTask() | Delegate task |
| mesh.updateTask() | Update task status |
| mesh.listTasks() | List tasks |
| mesh.shareDoc() | Share document |
| mesh.listDocs() | List shared docs |
| mesh.agents() | List all agents |
| mesh.stats() | Get mesh statistics |
| mesh.activity() | Get recent activity |
Examples
Register agent:
await client.mesh.register({
agentId: 'data-analyst',
displayName: 'Data Analyst Agent',
role: 'analyst',
status: 'online',
capabilities: ['sql', 'charts', 'reports'],
metadata: { model: 'gpt-4', version: '1.2.0' },
});Send different message types:
// Chat message
await client.mesh.send({
from: 'agent-a',
to: 'agent-b',
topic: 'Coffee chat',
body: 'Hey! Got a minute?',
type: 'chat',
priority: 'normal',
});
// Task assignment
await client.mesh.send({
from: 'manager-agent',
to: 'worker-agent',
topic: 'Data processing',
body: 'Process the CSV file in /data/imports/',
type: 'task',
priority: 'high',
});
// Alert
await client.mesh.send({
from: 'monitor-agent',
to: 'ops-agent',
topic: 'Server Down',
body: 'API server at 10.0.1.5 is not responding',
type: 'alert',
priority: 'urgent',
});Inbox filtering:
// Unread messages
const unread = await client.mesh.inbox({
agentId: 'my-agent',
direction: 'inbox',
status: 'sent',
});
// Tasks only
const tasks = await client.mesh.inbox({
agentId: 'my-agent',
direction: 'inbox',
messageType: 'task',
});
// Since timestamp
const recent = await client.mesh.inbox({
agentId: 'my-agent',
since: '2024-01-01T00:00:00Z',
limit: 50,
});Task delegation:
// Create task
const task = await client.mesh.assignTask({
assignedBy: 'lead-agent',
assignedTo: 'research-agent',
title: 'Market research',
description: 'Analyze Q4 trends in SaaS space',
priority: 'high',
dueAt: '2024-12-31T23:59:59Z',
});
// Update status
await client.mesh.updateTask(task.id, {
status: 'in_progress',
});
// Complete with result
await client.mesh.updateTask(task.id, {
status: 'completed',
result: 'Report uploaded to /reports/q4-saas-trends.pdf',
});Share knowledge:
await client.mesh.shareDoc({
sharedBy: 'research-agent',
path: 'knowledge/ml-best-practices',
title: 'Machine Learning Best Practices 2024',
content: '# ML Best Practices\n\n1. Always validate...',
tags: ['ml', 'best-practices', 'guide'],
pinned: true,
});Discover agents:
const agents = await client.mesh.agents();
for (const agent of agents) {
console.log(`${agent.display_name} (${agent.status})`);
console.log(` Role: ${agent.role}`);
console.log(` Capabilities: ${agent.capabilities.join(', ')}`);
}Mesh statistics:
const stats = await client.mesh.stats();
console.log(`Agents: ${stats.agents} (${stats.agents_online} online)`);
console.log(`Messages today: ${stats.messages_today}`);
console.log(`Active tasks: ${stats.tasks_active}`);
console.log(`Unread: ${stats.unread_messages}`);📱 Mobile Bridge
Control Android & iOS devices from your agent.
Operations
| Method | Description |
|--------|-------------|
| bridge.devices() | List connected devices |
| device.screenshot() | Capture screenshot |
| device.tap() | Tap at coordinates |
| device.tapElement() | Find & tap element |
| device.typeText() | Type text |
| device.swipe() | Swipe gesture |
| device.getUITree() | Get UI hierarchy |
| device.findElement() | Search for element |
| device.openApp() | Launch app |
| device.pressHome() | Press home button |
| device.pressBack() | Press back button |
Examples
List devices:
const devices = await client.bridge.devices();
for (const d of devices) {
console.log(`${d.model} (${d.platform}) - ${d.status}`);
}Take screenshot:
const phone = client.bridge.device('my-phone-id');
const screenshot = await phone.screenshot();
// Save to file
const fs = require('fs');
const buffer = Buffer.from(screenshot.imageBase64, 'base64');
fs.writeFileSync('screenshot.png', buffer);Tap on element:
// Tap by text
await phone.tapElement('text', 'Sign In');
// Tap by resource ID
await phone.tapElement('resourceId', 'com.example:id/login_button');
// Tap by content description
await phone.tapElement('contentDescription', 'Submit form');Type text:
await phone.typeText('[email protected]');
await phone.pressKey('ENTER');Swipe:
// Swipe up (scroll down)
await phone.swipe(540, 1200, 540, 400, 300);
// Swipe left
await phone.swipe(800, 960, 200, 960, 200);UI inspection:
const tree = await phone.getUITree();
console.log(`Active app: ${tree.activePackage}`);
// Find all buttons
const buttons = tree.nodes.filter(n =>
n.className.includes('Button') && n.clickable
);
for (const btn of buttons) {
console.log(`Button: "${btn.text}" at (${btn.bounds.left}, ${btn.bounds.top})`);
}App control:
// Launch app
await phone.openApp('com.twitter.android');
// Wait a bit
await new Promise(r => setTimeout(r, 2000));
// Navigate
await phone.pressHome();
await phone.openApp('com.instagram.android');⚡ WebSocket (Real-Time Events)
Subscribe to live updates across memory, mesh, kanban, and projects.
Event Types
| Event | Description |
|-------|-------------|
| memory:created | New memory stored |
| memory:updated | Memory modified |
| memory:deleted | Memory removed |
| mesh:agent_online | Agent came online |
| mesh:agent_offline | Agent went offline |
| mesh:message | Message received |
| mesh:task_update | Task status changed |
| kanban:task_created | Kanban task created |
| kanban:task_moved | Task moved to new column |
| kanban:task_completed | Task marked done |
| project:created | New project |
| project:updated | Project modified |
| project:activity | Activity logged |
Examples
Connect and subscribe:
// Connect
await client.connect();
// Listen for all memory events
client.ws.on('memory:created', (e) => {
console.log(`[MEMORY] Created: ${e.path}`);
});
client.ws.on('memory:updated', (e) => {
console.log(`[MEMORY] Updated: ${e.path}`);
});
client.ws.on('memory:deleted', (e) => {
console.log(`[MEMORY] Deleted: ${e.path}`);
});Mesh events:
// Agent presence
client.ws.on('mesh:agent_online', (e) => {
console.log(`[MESH] ${e.displayName} is online`);
});
client.ws.on('mesh:agent_offline', (e) => {
console.log(`[MESH] ${e.agentId} went offline`);
});
// Messages
client.ws.on('mesh:message', (e) => {
if (e.toAgent === 'my-agent') {
console.log(`[MESSAGE] From ${e.fromAgent}: ${e.body}`);
// Auto-reply
client.mesh.send({
from: 'my-agent',
to: e.fromAgent,
topic: `Re: ${e.topic}`,
body: 'Got it, thanks!',
parentId: e.messageId,
});
}
});
// Task updates
client.ws.on('mesh:task_update', (e) => {
if (e.assignedTo === 'my-agent' && e.status === 'pending') {
console.log(`[TASK] New task: ${e.title}`);
}
});Project events:
client.ws.on('project:activity', (e) => {
console.log(`[PROJECT] Activity logged: ${e.eventType}`);
});
client.ws.on('kanban:task_moved', (e) => {
console.log(`[KANBAN] Task moved: ${e.fromStatus} → ${e.toStatus}`);
});Disconnect:
// Clean up
client.disconnect();Clawdbot Integration
Installation
# Via ClawdHub
clawdhub install agentos
# Manual
cd ~/clawd/skills
git clone https://github.com/AgentOSsoftware/clawdbot-skill agentosConfiguration
Add to config.yaml:
env:
AGENTOS_API_KEY: "agfs_live_xxx.yyy"
AGENTOS_API_URL: "https://api.agentos.software"
AGENTOS_AGENT_ID: "my-agent"Sync Scripts
The Clawdbot skill includes automatic sync scripts:
Memory sync (every heartbeat):
~/clawd/bin/agentos-sync.shSyncs:
- CONTEXT.md
- Daily notes
- Project compartments
- MEMORY.md
- Learnings
- Mesh presence
Golden sync (memory + projects):
~/clawd/bin/agentos-golden-sync.shSyncs everything above PLUS:
- Project activity feed
- Project tasks
- Project ideas
- Project changelog
- Project challenges
Project-specific sync:
~/clawd/bin/agentos-project-sync.sh activity vulture "Fixed bug X" "bugfix"
~/clawd/bin/agentos-project-sync.sh task-update task-123 "done" "Completed feature Y"Add to Heartbeats
In your HEARTBEAT.md:
## AgentOS Sync (MANDATORY)
Every heartbeat, run: `~/clawd/bin/agentos-sync.sh`CLI Usage
The aos CLI provides quick access:
# Sync memory
aos sync
# Search
aos search "what did I work on yesterday"
# Mesh commands
aos mesh send kai "Need your help with X"
aos mesh inbox
aos mesh agents
# Memory operations
aos put context "Working on feature Y"
aos get context
aos list projects/
aos search "bug fixes"
# Status check
aos statusAPI Reference
AgentOSClient
const client = new AgentOSClient({
baseUrl: string;
apiKey: string;
agentId?: string;
ws?: ConnectionOptions;
});Memory Methods
// Store memory
client.put(args: {
path: string;
value: unknown;
ttlSeconds?: number;
tags?: string[];
importance?: number; // 0.0 - 1.0
searchable?: boolean;
idempotencyKey?: string;
}): Promise<PutResult>
// Get memory
client.get(path: string): Promise<GetResult>
// Delete
client.delete(path: string, opts?: { idempotencyKey?: string }): Promise<DeleteResult>
// List directory
client.list(prefix: string): Promise<ListResult>
// Glob pattern
client.glob(pattern: string): Promise<GlobResult>
// Version history
client.history(path: string, limit?: number): Promise<HistoryResult>
// Semantic search
client.search(args: {
query: string;
limit?: number;
pathPrefix?: string;
tagsAny?: string[];
}): Promise<SearchResponse>Mesh Methods
// Register agent
client.mesh.register(opts: {
agentId: string;
displayName: string;
role?: string;
status?: 'online' | 'offline' | 'busy';
capabilities?: string[];
metadata?: Record<string, unknown>;
}): Promise<MeshAgent>
// Send message
client.mesh.send(opts: {
from: string;
to: string;
topic: string;
body: string;
type?: 'chat' | 'task' | 'review' | 'research' | 'alert' | 'sync';
priority?: 'low' | 'normal' | 'high' | 'urgent';
metadata?: Record<string, unknown>;
parentId?: string;
}): Promise<MeshMessage>
// Get messages
client.mesh.inbox(opts: {
agentId: string;
direction?: 'inbox' | 'outbox' | 'all';
status?: 'sent' | 'delivered' | 'read' | 'archived';
messageType?: string;
since?: string;
limit?: number;
offset?: number;
}): Promise<MeshMessage[]>
// Mark as read
client.mesh.markRead(messageId: string): Promise<void>
// Assign task
client.mesh.assignTask(opts: {
assignedBy: string;
assignedTo: string;
title: string;
description?: string;
priority?: 'low' | 'normal' | 'high' | 'urgent';
dueAt?: string;
messageId?: string;
}): Promise<MeshTask>
// Update task
client.mesh.updateTask(taskId: string, opts: {
status?: 'pending' | 'in_progress' | 'completed' | 'failed' | 'cancelled';
result?: string;
}): Promise<MeshTask>
// List tasks
client.mesh.listTasks(opts?: {
assignedTo?: string;
assignedBy?: string;
status?: string;
limit?: number;
offset?: number;
}): Promise<MeshTask[]>
// Share document
client.mesh.shareDoc(opts: {
sharedBy: string;
path: string;
title: string;
content: string;
tags?: string[];
pinned?: boolean;
}): Promise<MeshSharedDoc>
// List shared docs
client.mesh.listDocs(opts?: {
tag?: string;
sharedBy?: string;
pinned?: boolean;
limit?: number;
offset?: number;
}): Promise<MeshSharedDoc[]>
// List agents
client.mesh.agents(): Promise<MeshAgent[]>
// Statistics
client.mesh.stats(): Promise<MeshStats>
// Recent activity
client.mesh.activity(limit?: number): Promise<MeshActivityItem[]>Bridge Methods
// List devices
client.bridge.devices(): Promise<BridgeDevice[]>
// Get device handle
const device = client.bridge.device(deviceId: string): DeviceHandle
// Device operations
device.screenshot(): Promise<ScreenshotResult>
device.tap(x: number, y: number): Promise<void>
device.tapElement(by: 'text' | 'resourceId' | 'contentDescription', value: string): Promise<void>
device.typeText(text: string): Promise<void>
device.swipe(x1: number, y1: number, x2: number, y2: number, durationMs: number): Promise<void>
device.getUITree(): Promise<UITreeResult>
device.findElement(by: 'text' | 'resourceId' | 'contentDescription', value: string): Promise<FindElementResult>
device.openApp(packageName: string): Promise<void>
device.pressHome(): Promise<void>
device.pressBack(): Promise<void>
device.pressKey(key: string): Promise<void>WebSocket Methods
// Connect
client.connect(): Promise<void>
// Disconnect
client.disconnect(): void
// Check connection
client.connected: boolean
// Event subscription
client.ws.on(event: WebSocketEventName, callback: Function): void
client.ws.off(event: WebSocketEventName, callback: Function): voidTroubleshooting
"Unauthorized" Error
Symptom: API returns 401 Unauthorized
Causes:
- Invalid API key
- Expired API key
- Wrong authorization header format
Fix:
// Check API key format
console.log(process.env.AGENTOS_API_KEY); // Should be agfs_live_xxx.yyy
// Verify authorization header
console.log(`Bearer ${apiKey}`); // Should NOT have extra quotesCreate a new API key if needed:
- Go to brain.agentos.software
- Settings → API Keys → Create API Key
Sync Script Not Running
Symptom: Dashboard not updating
Causes:
- Script doesn't have execute permissions
- API key not set
- Network connectivity issues
Fix:
# Check permissions
ls -la ~/clawd/bin/agentos-sync.sh
# Add execute permission if needed
chmod +x ~/clawd/bin/agentos-sync.sh
# Check API key
echo $AGENTOS_API_KEY
# Test connectivity
curl -s https://api.agentos.software/health \
-H "Authorization: Bearer $AGENTOS_API_KEY"WebSocket Connection Failed
Symptom: Real-time events not received
Causes:
- Firewall blocking WebSocket
- Invalid API key
- Network issues
Fix:
// Add connection logging
client.ws.on('connect', () => {
console.log('WebSocket connected!');
});
client.ws.on('connect_error', (error) => {
console.error('Connection error:', error);
});
client.ws.on('disconnect', (reason) => {
console.log('Disconnected:', reason);
});
// Check connection state
console.log('Connected:', client.connected);Search Returns No Results
Symptom: client.search() returns empty array
Causes:
- Memory not marked as
searchable: true - Query too specific
- No embeddings generated yet
Fix:
// Make sure memory is searchable
await client.put({
path: 'knowledge/docs',
value: { content: 'Machine learning guide' },
searchable: true, // ← IMPORTANT
tags: ['ml', 'guide'],
});
// Try broader query
const results = await client.search({
query: 'machine learning',
limit: 10,
});
// Check if ANY memory is searchable
const all = await client.list('knowledge/');
console.log('Total items:', all.items.length);Mobile Bridge Device Not Found
Symptom: bridge.devices() returns empty array
Causes:
- Mobile app not running
- Device not logged in
- Network connectivity
Fix:
- Open AgentOS mobile app on device
- Make sure you're logged in
- Check device appears as "online" in dashboard
- Verify device permissions (for iOS: Accessibility, for Android: Accessibility Service)
// Check device status
const devices = await client.bridge.devices();
console.log('Devices:', devices.map(d => ({
id: d.id,
model: d.model,
status: d.status,
lastSeen: d.lastSeenAt,
})));Memory Version Conflict
Symptom: 409 Conflict error when updating
Causes:
- Concurrent writes to same path
- No idempotency key used
Fix:
// Use idempotency key for retries
await client.put({
path: 'config/settings',
value: { theme: 'dark' },
idempotencyKey: 'update-theme-20240101', // Prevents duplicates
});
// For concurrent access, use different paths
await client.put({
path: `logs/${Date.now()}`,
value: { event: 'user_login' },
});Rate Limiting
Symptom: 429 Too Many Requests
Causes:
- Too many requests in short time
- Free tier limits reached
Fix:
// Add rate limiting
import pLimit from 'p-limit';
const limit = pLimit(5); // Max 5 concurrent requests
const promises = paths.map(path =>
limit(() => client.get(path))
);
await Promise.all(promises);Check your usage:
- Go to brain.agentos.software
- Settings → Usage
Support
- Documentation: docs.agentos.software
- Discord: discord.gg/agentos
- GitHub: github.com/AgentOSsoftware/agentos
- Email: [email protected]
License
MIT © MoonstoneLabs
