Skip to main content
Get up and running with AgentFS to build stateful, auditable AI agents in just a few minutes.

Prerequisites

  • Node.js 18+ or Rust 1.70+
  • Basic familiarity with async/await programming
  • An AI/LLM API key (optional, for agent examples)

Installation

  • TypeScript/JavaScript
  • Rust
npm install agentfs-sdk

Create Your First Agent

Let’s build a simple agent that maintains conversation history and generates files.
  • TypeScript
  • Rust
import { AgentFS } from 'agentfs-sdk';

// Initialize AgentFS with a local database
const agent = await AgentFS.open(
  './my-agent.db'
);

// Store agent configuration
await agent.kv.set('agent:id', 'assistant-001');
await agent.kv.set(
  'agent:created',
  new Date().toISOString()
);

// Create a conversation history
const conversations = [];

async function addMessage(role: string, content: string) {
  const message = {
    role,
    content,
    timestamp: Date.now()
  };

  conversations.push(message);

  // Persist to AgentFS
  await agent.kv.set('conversations', conversations);

  // Also save as a file for easy access
  const filename = `/conversations/${Date.now()}.json`;
  await agent.fs.writeFile(
    filename,
    JSON.stringify(message, null, 2)
  );

  // Track this as a tool call
  await agent.tools.record(
    'save_message',
    Date.now() / 1000,
    Date.now() / 1000 + 0.1,
    { role, contentLength: content.length },
    { saved: true, filename }
  );
}

// Example usage
await addMessage(
  'user',
  'Hello, can you help me with a task?'
);
await addMessage(
  'assistant',
  'Of course! I'd be happy to help.'
);

// Retrieve conversation history
const history = await agent.kv.get('conversations');
console.log('Conversation history:', history);

// List all conversation files
const files = await agent.fs.readdir('/conversations');
console.log('Saved conversations:', files);

Working with Files

AgentFS provides a POSIX-like filesystem API for managing agent-generated content:
// Create directories
await agent.fs.mkdir('/reports');
await agent.fs.mkdir('/reports/2024');

// Write files
const report = "# Q4 2024 Analysis\n\nKey findings...";
await agent.fs.writeFile(
  '/reports/2024/q4-analysis.md',
  report
);

// Read files
const content = await agent.fs.readFile(
  '/reports/2024/q4-analysis.md'
);
console.log(content.toString());

// List directory contents
const reports = await agent.fs.readdir('/reports/2024');
console.log('Available reports:', reports);

// Check file metadata
const stats = await agent.fs.stat(
  '/reports/2024/q4-analysis.md'
);
console.log('File size:', stats.size);
console.log('Created:', new Date(stats.ctime * 1000));

Managing Agent State

Use the key-value store for fast access to agent configuration and state:
// Store structured data
await agent.kv.set('user:preferences', {
  theme: 'dark',
  language: 'en',
  notifications: true
});

// Store conversation context
await agent.kv.set('context:current', {
  topic: 'data analysis',
  tools: ['calculator', 'chart_generator'],
  startTime: Date.now()
});

// Retrieve values
const preferences = await agent.kv.get('user:preferences');
const context = await agent.kv.get('context:current');

// Delete keys
await agent.kv.delete('context:previous');

// List all keys with a prefix
const userKeys = await agent.kv.list({ prefix: 'user:' });
console.log('User data keys:', userKeys);

Tracking Tool Calls

Every tool invocation can be automatically tracked for debugging and compliance:
// Record a web search
const startTime = Date.now() / 1000;
const results = await performWebSearch(
  'AgentFS tutorial'
);
const endTime = Date.now() / 1000;

await agent.tools.record(
  'web_search',
  startTime,
  endTime,
  { query: 'AgentFS tutorial', maxResults: 10 },
  {
    resultsFound: results.length,
    topResult: results[0]?.url
  }
);

// Record an API call
await agent.tools.record(
  'openai_completion',
  Date.now() / 1000,
  Date.now() / 1000 + 2.5,
  { model: 'gpt-4', temperature: 0.7 },
  { tokensUsed: 1500, success: true }
);

// Query tool usage
const recentTools = await agent.tools.list({ limit: 10 });
console.log('Recent tool calls:', recentTools);

// Get specific tool call
const toolCall = await agent.tools.get(recentTools[0].id);
console.log('Tool details:', toolCall);

Querying Agent History

Since AgentFS is built on Turso, you can query your agent’s behavior with SQL:
// Get the underlying database connection
const db = agent.db;

// Find all files created in the last hour
const recentFiles = await db.prepare(`
  SELECT * FROM events
  WHERE type = 'file_write'
  AND timestamp > datetime('now', '-1 hour')
  ORDER BY timestamp DESC
`).all();

// Analyze tool usage patterns
const toolStats = await db.prepare(`
  SELECT
    name as tool_name,
    COUNT(*) as usage_count,
    AVG(julianday(ended_at) -
        julianday(started_at)) * 86400
        as avg_duration_seconds
  FROM toolcalls
  GROUP BY name
  ORDER BY usage_count DESC
`).all();

console.log('Tool usage statistics:', toolStats);

Best Practices

1. Structure Your Filesystem

Organize files logically for easy navigation:
/
├── conversations/     # Chat histories
├── outputs/          # Generated content
├── cache/           # Temporary data
├── logs/            # Agent logs
└── config/          # Configuration files

2. Use Consistent Key Naming

Adopt a naming convention for KV store keys:
// Good: Hierarchical and clear
await agent.kv.set(
  'user:123:preferences', {...}
);
await agent.kv.set(
  'session:abc:context', {...}
);
await agent.kv.set(
  'cache:api:response:xyz', {...}
);

// Avoid: Flat and ambiguous
await agent.kv.set('prefs', {...});
await agent.kv.set('data1', {...});

3. Track Important Operations

Record tool calls for critical operations:
async function generateReport(data: any) {
  const start = Date.now() / 1000;

  try {
    const report = await createReport(data);

    await agent.tools.record(
      'generate_report',
      start,
      Date.now() / 1000,
      { dataSize: data.length },
      { success: true, reportId: report.id }
    );

    return report;
  } catch (error) {
    await agent.tools.record(
      'generate_report',
      start,
      Date.now() / 1000,
      { dataSize: data.length },
      { success: false, error: error.message }
    );
    throw error;
  }
}

Next Steps