JSPM

@agentos_software_org/sdk

1.1.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 14
  • Score
    100M100P100Q39627F
  • License MIT

Official TypeScript SDK for AgentOS — persistent memory, semantic search, and inter-agent mesh for AI agents

Package Exports

  • @agentos_software_org/sdk
  • @agentos_software_org/sdk/bridge
  • @agentos_software_org/sdk/graph
  • @agentos_software_org/sdk/kanban
  • @agentos_software_org/sdk/manage
  • @agentos_software_org/sdk/mesh
  • @agentos_software_org/sdk/metrics
  • @agentos_software_org/sdk/projects
  • @agentos_software_org/sdk/webhooks
  • @agentos_software_org/sdk/websocket

Readme

@agentos/sdk

AgentOS

npm version license TypeScript Node.js

Official TypeScript/JavaScript SDK for AgentOS
Persistent memory • Inter-agent mesh • Mobile control • Real-time events

InstallationQuick StartFeaturesAPI ReferenceTroubleshooting


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 agentos

For Node.js Projects

npm install @agentos/sdk
pnpm add @agentos/sdk
yarn add @agentos/sdk

Setup

1. Create Your Account

Go to brain.agentos.software and:

  1. Click "Login with Google"
  2. Complete onboarding (enter display name)
  3. You're in! 🎉

2. Get API Key

  1. Go to SettingsAPI Keys
  2. Click "Create API Key"
  3. Give it a name (e.g., "My Agent")
  4. 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' }
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('hello@example.com');
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 agentos

Configuration

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.sh

Syncs:

  • CONTEXT.md
  • Daily notes
  • Project compartments
  • MEMORY.md
  • Learnings
  • Mesh presence

Golden sync (memory + projects):

~/clawd/bin/agentos-golden-sync.sh

Syncs 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 status

API 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): void

Troubleshooting

"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 quotes

Create a new API key if needed:

  1. Go to brain.agentos.software
  2. 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:

  1. Open AgentOS mobile app on device
  2. Make sure you're logged in
  3. Check device appears as "online" in dashboard
  4. 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:

  1. Go to brain.agentos.software
  2. Settings → Usage

Support


License

MIT © MoonstoneLabs