Skip to content

Commit 777d18c

Browse files
committed
Add support for syncing filesystem to Turso Cloud
1 parent 932280e commit 777d18c

File tree

5 files changed

+484
-8
lines changed

5 files changed

+484
-8
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { AgentFS, tursoSync } from "agentfs-sdk";
2+
3+
/**
4+
* Simple Turso Cloud Sync Example
5+
*
6+
* This example demonstrates the minimal setup for syncing an AgentFS instance
7+
* with Turso Cloud using environment variables.
8+
*
9+
* Prerequisites:
10+
* - Set TURSO_API_TOKEN environment variable with your Turso API token
11+
* - Optionally set TURSO_API_ORG (defaults to your primary org)
12+
*
13+
* The sync provider will automatically:
14+
* 1. Create a database named 'simple-agent' if it doesn't exist
15+
* 2. Generate an auth token for the database
16+
* 3. Setup bidirectional sync
17+
* 4. Enable auto-sync every 60 seconds
18+
*/
19+
async function main() {
20+
console.log("=== Simple Turso Cloud Sync Example ===\n");
21+
22+
// Check for required environment variable
23+
if (!process.env.TURSO_API_TOKEN) {
24+
console.error("Error: TURSO_API_TOKEN environment variable is required");
25+
console.error("Get your token from: https://turso.tech/app");
26+
process.exit(1);
27+
}
28+
29+
// Open AgentFS with Turso Cloud sync
30+
// This will create a database named 'simple-agent' in Turso Cloud
31+
console.log("Opening AgentFS with Turso Cloud sync...");
32+
const agent = await AgentFS.open({
33+
id: "simple-agent",
34+
sync: tursoSync(), // Uses all defaults from environment variables
35+
});
36+
37+
console.log("✓ Connected to Turso Cloud\n");
38+
39+
// Store some data
40+
console.log("Storing data locally...");
41+
await agent.kv.set("greeting", "Hello from AgentFS!");
42+
await agent.kv.set("timestamp", new Date().toISOString());
43+
await agent.kv.set("counter", 42);
44+
45+
console.log("✓ Data stored locally\n");
46+
47+
// Manual sync to cloud
48+
console.log("Syncing to Turso Cloud...");
49+
await agent.sync!.push();
50+
console.log("✓ Data pushed to cloud\n");
51+
52+
// Check sync status
53+
const status = agent.sync!.getStatus();
54+
console.log("Sync status:", {
55+
state: status.state,
56+
lastSync: status.lastSync?.toISOString(),
57+
});
58+
59+
console.log("\n=== Auto-sync is enabled ===");
60+
console.log("Your data will automatically sync every 60 seconds.");
61+
console.log("Try modifying the cloud database and run this again to see changes pulled down.\n");
62+
63+
// Cleanup
64+
await agent.close();
65+
console.log("✓ Connection closed");
66+
}
67+
68+
main().catch((error) => {
69+
console.error("Error:", error.message);
70+
process.exit(1);
71+
});

sdk/typescript/package.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "agentfs-sdk",
3-
"version": "0.1.2",
3+
"version": "0.2.0",
44
"description": "AgentFS SDK",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",
@@ -20,7 +20,9 @@
2020
"turso",
2121
"sqlite",
2222
"key-value",
23-
"filesystem"
23+
"filesystem",
24+
"sync",
25+
"cloud"
2426
],
2527
"author": "",
2628
"license": "MIT",
@@ -33,6 +35,10 @@
3335
"dependencies": {
3436
"@tursodatabase/database": "^0.3.2"
3537
},
38+
"optionalDependencies": {
39+
"@tursodatabase/api": "^1.9.0",
40+
"@tursodatabase/sync": "^0.3.2"
41+
},
3642
"files": [
3743
"dist"
3844
]

sdk/typescript/src/index.ts

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { existsSync, mkdirSync } from 'fs';
33
import { KvStore } from './kvstore';
44
import { Filesystem } from './filesystem';
55
import { ToolCalls } from './toolcalls';
6+
import type { SyncProvider, TursoSyncFactory } from './sync';
7+
import { TursoSyncProvider } from './providers/turso';
68

79
/**
810
* Configuration options for opening an AgentFS instance
@@ -14,8 +16,13 @@ export interface AgentFSOptions {
1416
* - If omitted: Uses ephemeral in-memory database
1517
*/
1618
id?: string;
17-
// Future: sync configuration will be added here
18-
// sync?: SyncConfig;
19+
20+
/**
21+
* Optional sync configuration
22+
* - Pass a TursoSyncFactory from tursoSync() for Turso Cloud sync
23+
* - Pass a custom SyncProvider for other backends
24+
*/
25+
sync?: TursoSyncFactory | SyncProvider;
1926
}
2027

2128
export class AgentFS {
@@ -24,15 +31,23 @@ export class AgentFS {
2431
public readonly kv: KvStore;
2532
public readonly fs: Filesystem;
2633
public readonly tools: ToolCalls;
34+
public readonly sync?: SyncProvider;
2735

2836
/**
2937
* Private constructor - use AgentFS.open() instead
3038
*/
31-
private constructor(db: Database, kv: KvStore, fs: Filesystem, tools: ToolCalls) {
39+
private constructor(
40+
db: Database,
41+
kv: KvStore,
42+
fs: Filesystem,
43+
tools: ToolCalls,
44+
sync?: SyncProvider
45+
) {
3246
this.db = db;
3347
this.kv = kv;
3448
this.fs = fs;
3549
this.tools = tools;
50+
this.sync = sync;
3651
}
3752

3853
/**
@@ -47,6 +62,13 @@ export class AgentFS {
4762
*
4863
* // Ephemeral in-memory database
4964
* const agent = await AgentFS.open();
65+
*
66+
* // With Turso Cloud sync
67+
* import { tursoSync } from 'agentfs-sdk';
68+
* const agent = await AgentFS.open({
69+
* id: 'my-agent',
70+
* sync: tursoSync()
71+
* });
5072
* ```
5173
*/
5274
static async open(options?: AgentFSOptions): Promise<AgentFS> {
@@ -60,7 +82,7 @@ export class AgentFS {
6082
);
6183
}
6284

63-
const { id } = options || {};
85+
const { id, sync } = options || {};
6486

6587
// Determine database path based on id
6688
let dbPath: string;
@@ -91,8 +113,22 @@ export class AgentFS {
91113
await fs.ready();
92114
await tools.ready();
93115

116+
// Initialize sync if configured
117+
let syncProvider: SyncProvider | undefined;
118+
if (sync) {
119+
if ('__type' in sync && sync.__type === 'turso-sync-factory') {
120+
// Turso sync factory
121+
syncProvider = new TursoSyncProvider(db, id || 'default', sync.config);
122+
} else {
123+
// Custom sync provider
124+
syncProvider = sync as SyncProvider;
125+
}
126+
127+
await syncProvider.initialize();
128+
}
129+
94130
// Return fully initialized instance
95-
return new AgentFS(db, kv, fs, tools);
131+
return new AgentFS(db, kv, fs, tools, syncProvider);
96132
}
97133

98134
/**
@@ -103,9 +139,12 @@ export class AgentFS {
103139
}
104140

105141
/**
106-
* Close the database connection
142+
* Close the database connection and cleanup sync
107143
*/
108144
async close(): Promise<void> {
145+
if (this.sync) {
146+
await this.sync.cleanup();
147+
}
109148
await this.db.close();
110149
}
111150
}
@@ -115,3 +154,5 @@ export { Filesystem } from './filesystem';
115154
export type { Stats } from './filesystem';
116155
export { ToolCalls } from './toolcalls';
117156
export type { ToolCall, ToolCallStats } from './toolcalls';
157+
export { tursoSync } from './sync';
158+
export type { SyncProvider, TursoSyncConfig, SyncStatus } from './sync';

0 commit comments

Comments
 (0)