AgentFS

Struct AgentFS 

Source
pub struct AgentFS {
    pub fs: DbFileSystem,
    pub kv: DbKvStore,
    pub tools: DbToolRecorder,
    pub agent_id: String,
    pub mount_path: PathBuf,
}
Expand description

Main AgentFS struct providing filesystem, KV store, and tool recording

Fields§

§fs: DbFileSystem

Filesystem operations

§kv: DbKvStore

Key-value store

§tools: DbToolRecorder

Tool call recorder

§agent_id: String

Agent identifier

§mount_path: PathBuf

Mount path for the filesystem

Implementations§

Source§

impl AgentFS

Source

pub async fn new( db: Box<dyn AgentDB>, agent_id: impl Into<String>, mount_path: impl Into<PathBuf>, ) -> Result<Self>

Create a new AgentFS instance

§Arguments
  • db - Database backend implementing AgentDB trait
  • agent_id - Unique identifier for this agent
  • mount_path - Virtual mount path for the filesystem (default: “/agent”)
§Example
let backend = SqlBackend::sqlite("agent.db").await?;
let agent_fs = AgentFS::new(Box::new(backend), "my-agent", "/agent").await?;
Examples found in repository?
examples/basic.rs (line 21)
15async fn main() -> Result<(), Box<dyn std::error::Error>> {
16    println!("=== AgentFS Basic Example (SQLite) ===\n");
17
18    // Create a SQLite-backed agent filesystem
19    println!("1. Initializing SQLite backend...");
20    let backend = SqlBackend::sqlite("agent_example.db").await?;
21    let agent_fs = AgentFS::new(Box::new(backend), "demo-agent", "/agent").await?;
22    println!("   ✓ AgentFS initialized with agent_id: {}\n", agent_fs.agent_id());
23
24    // File Operations
25    println!("2. File Operations:");
26
27    // Create a directory
28    agent_fs.fs.mkdir("/output").await?;
29    println!("   ✓ Created directory: /output");
30
31    // Write a file
32    let report_content = b"# Agent Report\n\nThis is a test report generated by the agent.";
33    agent_fs.fs.write_file("/output/report.md", report_content).await?;
34    println!("   ✓ Wrote file: /output/report.md");
35
36    // Read the file back
37    let read_content = agent_fs.fs.read_file("/output/report.md").await?.unwrap();
38    println!("   ✓ Read file: /output/report.md ({} bytes)", read_content.len());
39
40    // List directory contents
41    let entries = agent_fs.fs.readdir("/output").await?.unwrap();
42    println!("   ✓ Directory /output contains: {:?}\n", entries);
43
44    // Key-Value Store Operations
45    println!("3. Key-Value Store Operations:");
46
47    // Store session state
48    agent_fs.kv.set("session:id", b"abc-123-def").await?;
49    agent_fs.kv.set("session:user", b"alice").await?;
50    agent_fs.kv.set("config:theme", b"dark").await?;
51    println!("   ✓ Stored 3 key-value pairs");
52
53    // Retrieve a value
54    let session_id = agent_fs.kv.get("session:id").await?.unwrap();
55    println!("   ✓ Retrieved session:id = {}", String::from_utf8_lossy(&session_id));
56
57    // Scan with prefix
58    let session_keys = agent_fs.kv.scan("session:").await?;
59    println!("   ✓ Keys with prefix 'session:': {:?}\n", session_keys);
60
61    // Tool Call Recording (Workflow-based API)
62    println!("4. Tool Call Recording:");
63
64    // Start a tool call
65    let params = serde_json::json!({
66        "query": "What is the weather in San Francisco?",
67        "location": "San Francisco, CA"
68    });
69    let call_id = agent_fs.tools.start("weather_api", Some(params)).await?;
70    println!("   ✓ Started tool call (ID: {})", call_id);
71
72    // Simulate tool execution
73    tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
74
75    // Mark as successful
76    let result = serde_json::json!({
77        "temperature": 65,
78        "condition": "Sunny",
79        "humidity": 60
80    });
81    agent_fs.tools.success(call_id, Some(result)).await?;
82    println!("   ✓ Marked tool call as successful");
83
84    // Get tool call details
85    let tool_call = agent_fs.tools.get(call_id).await?.unwrap();
86    println!("   ✓ Tool call status: {:?}", tool_call.status);
87    println!("   ✓ Duration: {} ms\n", tool_call.duration_ms.unwrap_or(0));
88
89    // Record another tool call (single-shot API)
90    println!("5. Single-Shot Tool Recording:");
91
92    let start = std::time::SystemTime::now()
93        .duration_since(std::time::UNIX_EPOCH)?
94        .as_secs() as i64;
95
96    tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
97
98    let end = std::time::SystemTime::now()
99        .duration_since(std::time::UNIX_EPOCH)?
100        .as_secs() as i64;
101
102    let db_call_id = agent_fs.tools.record(
103        "database_query",
104        start,
105        end,
106        Some(serde_json::json!({"table": "users", "limit": 10})),
107        Some(serde_json::json!({"rows": 10})),
108        None,
109    ).await?;
110    println!("   ✓ Recorded database_query tool call (ID: {})\n", db_call_id);
111
112    // Get statistics
113    println!("6. Tool Call Statistics:");
114
115    // Create a few more tool calls for stats
116    for i in 0..3 {
117        let id = agent_fs.tools.start("api_request", None).await?;
118        tokio::time::sleep(tokio::time::Duration::from_millis(20)).await;
119        if i < 2 {
120            agent_fs.tools.success(id, None).await?;
121        } else {
122            agent_fs.tools.error(id, "Timeout").await?;
123        }
124    }
125
126    let stats = agent_fs.tools.stats_for("api_request").await?.unwrap();
127    println!("   Tool: {}", stats.name);
128    println!("   Total calls: {}", stats.total_calls);
129    println!("   Successful: {}", stats.successful);
130    println!("   Failed: {}", stats.failed);
131    println!("   Avg duration: {:.2} ms\n", stats.avg_duration_ms);
132
133    println!("=== Example Complete ===");
134    println!("\nDatabase file created: agent_example.db");
135    println!("You can inspect it with: sqlite3 agent_example.db");
136
137    Ok(())
138}
Source

pub async fn sqlite( path: impl AsRef<Path>, agent_id: impl Into<String>, ) -> Result<Self>

Convenience constructor for SQLite backend

Source

pub fn agent_id(&self) -> &str

Get the agent ID

Examples found in repository?
examples/basic.rs (line 22)
15async fn main() -> Result<(), Box<dyn std::error::Error>> {
16    println!("=== AgentFS Basic Example (SQLite) ===\n");
17
18    // Create a SQLite-backed agent filesystem
19    println!("1. Initializing SQLite backend...");
20    let backend = SqlBackend::sqlite("agent_example.db").await?;
21    let agent_fs = AgentFS::new(Box::new(backend), "demo-agent", "/agent").await?;
22    println!("   ✓ AgentFS initialized with agent_id: {}\n", agent_fs.agent_id());
23
24    // File Operations
25    println!("2. File Operations:");
26
27    // Create a directory
28    agent_fs.fs.mkdir("/output").await?;
29    println!("   ✓ Created directory: /output");
30
31    // Write a file
32    let report_content = b"# Agent Report\n\nThis is a test report generated by the agent.";
33    agent_fs.fs.write_file("/output/report.md", report_content).await?;
34    println!("   ✓ Wrote file: /output/report.md");
35
36    // Read the file back
37    let read_content = agent_fs.fs.read_file("/output/report.md").await?.unwrap();
38    println!("   ✓ Read file: /output/report.md ({} bytes)", read_content.len());
39
40    // List directory contents
41    let entries = agent_fs.fs.readdir("/output").await?.unwrap();
42    println!("   ✓ Directory /output contains: {:?}\n", entries);
43
44    // Key-Value Store Operations
45    println!("3. Key-Value Store Operations:");
46
47    // Store session state
48    agent_fs.kv.set("session:id", b"abc-123-def").await?;
49    agent_fs.kv.set("session:user", b"alice").await?;
50    agent_fs.kv.set("config:theme", b"dark").await?;
51    println!("   ✓ Stored 3 key-value pairs");
52
53    // Retrieve a value
54    let session_id = agent_fs.kv.get("session:id").await?.unwrap();
55    println!("   ✓ Retrieved session:id = {}", String::from_utf8_lossy(&session_id));
56
57    // Scan with prefix
58    let session_keys = agent_fs.kv.scan("session:").await?;
59    println!("   ✓ Keys with prefix 'session:': {:?}\n", session_keys);
60
61    // Tool Call Recording (Workflow-based API)
62    println!("4. Tool Call Recording:");
63
64    // Start a tool call
65    let params = serde_json::json!({
66        "query": "What is the weather in San Francisco?",
67        "location": "San Francisco, CA"
68    });
69    let call_id = agent_fs.tools.start("weather_api", Some(params)).await?;
70    println!("   ✓ Started tool call (ID: {})", call_id);
71
72    // Simulate tool execution
73    tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
74
75    // Mark as successful
76    let result = serde_json::json!({
77        "temperature": 65,
78        "condition": "Sunny",
79        "humidity": 60
80    });
81    agent_fs.tools.success(call_id, Some(result)).await?;
82    println!("   ✓ Marked tool call as successful");
83
84    // Get tool call details
85    let tool_call = agent_fs.tools.get(call_id).await?.unwrap();
86    println!("   ✓ Tool call status: {:?}", tool_call.status);
87    println!("   ✓ Duration: {} ms\n", tool_call.duration_ms.unwrap_or(0));
88
89    // Record another tool call (single-shot API)
90    println!("5. Single-Shot Tool Recording:");
91
92    let start = std::time::SystemTime::now()
93        .duration_since(std::time::UNIX_EPOCH)?
94        .as_secs() as i64;
95
96    tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
97
98    let end = std::time::SystemTime::now()
99        .duration_since(std::time::UNIX_EPOCH)?
100        .as_secs() as i64;
101
102    let db_call_id = agent_fs.tools.record(
103        "database_query",
104        start,
105        end,
106        Some(serde_json::json!({"table": "users", "limit": 10})),
107        Some(serde_json::json!({"rows": 10})),
108        None,
109    ).await?;
110    println!("   ✓ Recorded database_query tool call (ID: {})\n", db_call_id);
111
112    // Get statistics
113    println!("6. Tool Call Statistics:");
114
115    // Create a few more tool calls for stats
116    for i in 0..3 {
117        let id = agent_fs.tools.start("api_request", None).await?;
118        tokio::time::sleep(tokio::time::Duration::from_millis(20)).await;
119        if i < 2 {
120            agent_fs.tools.success(id, None).await?;
121        } else {
122            agent_fs.tools.error(id, "Timeout").await?;
123        }
124    }
125
126    let stats = agent_fs.tools.stats_for("api_request").await?.unwrap();
127    println!("   Tool: {}", stats.name);
128    println!("   Total calls: {}", stats.total_calls);
129    println!("   Successful: {}", stats.successful);
130    println!("   Failed: {}", stats.failed);
131    println!("   Avg duration: {:.2} ms\n", stats.avg_duration_ms);
132
133    println!("=== Example Complete ===");
134    println!("\nDatabase file created: agent_example.db");
135    println!("You can inspect it with: sqlite3 agent_example.db");
136
137    Ok(())
138}
Source

pub fn mount_path(&self) -> &PathBuf

Get the mount path

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more