Skip to content

Commit 9e8a105

Browse files
feat(rust): add initial aios-rs scaffold with core traits and README integration
1 parent dc220f1 commit 9e8a105

File tree

12 files changed

+366
-0
lines changed

12 files changed

+366
-0
lines changed

README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,41 @@ Make sure you have installed a virtualized environment with GUI, then you can re
374374
| Novita | [All Models](https://novita.ai/models/llm) | ✅ | model-name | novita | NOVITA_API_KEY |
375375
376376
## Reference
377+
\n+## 🔧 Experimental Rust Rewrite (aios-rs)
378+
An early experimental Rust scaffold lives in `aios-rs/` providing trait definitions and minimal placeholder implementations (context, memory, storage, tool, scheduler, llm). This is NOT feature-parity yet; it's a foundation for incremental porting and performance-focused components.
379+
380+
### Try It
381+
```bash
382+
cd aios-rs
383+
cargo build
384+
cargo test
385+
```
386+
387+
### Example (Echo LLM + Noop Scheduler)
388+
```rust
389+
use aios_rs::prelude::*;
390+
391+
fn main() -> anyhow::Result<()> {
392+
let llm = std::sync::Arc::new(EchoLLM);
393+
let memory = std::sync::Arc::new(std::sync::Mutex::new(InMemoryMemoryManager::new()));
394+
let storage = std::sync::Arc::new(FsStorageManager::new("/tmp/aios_store"));
395+
let tool = std::sync::Arc::new(NoopToolManager);
396+
let mut scheduler = NoopScheduler::new(llm, memory, storage, tool);
397+
scheduler.start()?;
398+
scheduler.stop()?;
399+
Ok(())
400+
}
401+
```
402+
403+
### Roadmap Snapshot
404+
- [x] Core trait scaffolding
405+
- [ ] Async runtime + channels
406+
- [ ] Vector store abstraction
407+
- [ ] Python bridge (pyo3 / IPC)
408+
- [ ] Port FIFO / RR schedulers
409+
- [ ] Benchmarks & feature flags
410+
411+
Contributions welcome via focused PRs extending this scaffold. See `aios-rs/README.md` for details.
377412
```
378413
@article{mei2025litecua,
379414
title={LiteCUA: Computer as MCP Server for Computer-Use Agent on AIOS},

aios-rs/Cargo.lock

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

aios-rs/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "aios-rs"
3+
version = "0.1.0"
4+
edition = "2024"
5+
description = "Experimental Rust rewrite scaffold of the AIOS framework"
6+
license = "Apache-2.0"
7+
repository = "https://github.com/agiresearch/AIOS"
8+
readme = "README.md"
9+
10+
[dependencies]
11+
anyhow = "1"

aios-rs/README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# aios-rs
2+
3+
Experimental Rust rewrite scaffold of the AIOS framework. This is an early foundation providing core trait definitions and minimal reference implementations so that the Python system can be incrementally ported / inter-operated.
4+
5+
## Status
6+
- Traits defined: context, memory, storage, tool, scheduler, llm adapter
7+
- Minimal in-memory / filesystem / echo implementations
8+
- No async runtime yet (Tokio not added)
9+
- No vector DB / embedding integration yet
10+
- No FFI bridge to Python yet
11+
12+
## Goals (incremental roadmap)
13+
1. Flesh out trait contracts (streaming, structured errors, async)
14+
2. Provide concrete async implementations (Tokio + channels)
15+
3. Add vector store abstraction + pluggable backends
16+
4. Introduce pyo3 / JSON-RPC bridge for hybrid operation
17+
5. Port scheduling strategies (FIFO, RR) with test parity
18+
6. Add feature flags: `vector`, `python-bridge`, `tokio-scheduler`
19+
7. Performance + memory benchmarks
20+
21+
## Quick Start
22+
```bash
23+
# In repository root
24+
cd aios-rs
25+
cargo test
26+
```
27+
28+
Add to another crate (path dependency while developing):
29+
```toml
30+
[dependencies]
31+
aios-rs = { path = "../aios-rs" }
32+
```
33+
34+
Example usage:
35+
```rust
36+
use aios_rs::prelude::*;
37+
38+
fn main() -> anyhow::Result<()> {
39+
let llm = std::sync::Arc::new(EchoLLM);
40+
let memory = std::sync::Arc::new(std::sync::Mutex::new(InMemoryMemoryManager::new()));
41+
let storage = std::sync::Arc::new(FsStorageManager::new("/tmp/aios_store"));
42+
let tool = std::sync::Arc::new(NoopToolManager);
43+
let mut scheduler = NoopScheduler::new(llm, memory, storage, tool);
44+
scheduler.start()?;
45+
scheduler.stop()?;
46+
Ok(())
47+
}
48+
```
49+
50+
## Contributing
51+
This scaffold intentionally keeps scope narrow; please open an issue or discussion before expanding new subsystems. Focus areas welcome: async design, error model, bridging strategy, test parity with Python.
52+
53+
## License
54+
Apache-2.0

aios-rs/src/context.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//! Context subsystem (snapshot + recovery) trait definitions.
2+
use std::path::PathBuf;
3+
4+
pub trait ContextManager: Send + Sync {
5+
fn start(&mut self) -> anyhow::Result<()> { Ok(()) }
6+
fn gen_snapshot(&self, pid: u64, context: &str) -> anyhow::Result<PathBuf>;
7+
fn gen_recover(&self, pid: u64) -> anyhow::Result<Option<String>>;
8+
fn stop(&mut self) -> anyhow::Result<()> { Ok(()) }
9+
}
10+
11+
/// A minimal in-memory context manager placeholder.
12+
pub struct InMemoryContextManager {
13+
root: PathBuf,
14+
}
15+
16+
impl InMemoryContextManager {
17+
pub fn new(root: impl Into<PathBuf>) -> Self { Self { root: root.into() } }
18+
}
19+
20+
impl ContextManager for InMemoryContextManager {
21+
fn gen_snapshot(&self, pid: u64, context: &str) -> anyhow::Result<PathBuf> {
22+
let file = self.root.join(format!("ctx_{pid}.txt"));
23+
std::fs::create_dir_all(&self.root)?;
24+
std::fs::write(&file, context)?;
25+
Ok(file)
26+
}
27+
fn gen_recover(&self, pid: u64) -> anyhow::Result<Option<String>> {
28+
let file = self.root.join(format!("ctx_{pid}.txt"));
29+
if file.exists() { Ok(Some(std::fs::read_to_string(file)?)) } else { Ok(None) }
30+
}
31+
}

aios-rs/src/lib.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//! aios-rs: Experimental Rust rewrite scaffold of the AIOS framework.
2+
//!
3+
//! This crate currently provides trait definitions and minimal placeholder
4+
//! implementations mirroring the Python architecture (context, memory,
5+
//! scheduler, storage, tool, llm adapter). The goal is to iteratively port
6+
//! functionality while keeping a clear boundary for mixed-language operation.
7+
//!
8+
//! Roadmap (high-level):
9+
//! 1. Define core traits (done in this scaffold)
10+
//! 2. Implement in-memory versions + simple examples
11+
//! 3. Provide FFI / IPC bridge (e.g., via pyo3 or JSON-RPC) to allow gradual
12+
//! replacement of Python components
13+
//! 4. Optimize concurrency (Tokio) and memory management
14+
//! 5. Add feature flags for optional subsystems (vector db, scheduler variants)
15+
//!
16+
//! The code here is intentionally minimal; it is a foundation for further PRs.
17+
18+
pub mod context;
19+
pub mod memory;
20+
pub mod scheduler;
21+
pub mod storage;
22+
pub mod tool;
23+
pub mod llm;
24+
pub mod prelude;
25+
26+
// Re-export common traits for ergonomics.
27+
pub use context::ContextManager;
28+
pub use memory::{MemoryManager, MemoryNote, MemoryQuery, MemoryResponse};
29+
pub use scheduler::Scheduler;
30+
pub use storage::StorageManager;
31+
pub use tool::ToolManager;
32+
pub use llm::{LLMAdapter, LLMRequest, LLMResponse};
33+
34+
/// Version of the Rust rewrite scaffold (distinct from crate version if needed)
35+
pub const AIOS_RS_SCAFFOLD_VERSION: &str = "0.0.1-alpha";
36+
37+
#[cfg(test)]
38+
mod tests {
39+
use super::*;
40+
41+
#[test]
42+
fn version_constant_present() {
43+
assert_eq!(AIOS_RS_SCAFFOLD_VERSION, "0.0.1-alpha");
44+
}
45+
}

aios-rs/src/llm.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//! LLM adapter trait and simple echo implementation.
2+
use anyhow::Result;
3+
4+
pub trait LLMAdapter: Send + Sync {
5+
fn infer(&self, request: LLMRequest) -> Result<LLMResponse>;
6+
}
7+
8+
#[derive(Debug, Clone)]
9+
pub struct LLMRequest { pub prompt: String }
10+
#[derive(Debug, Clone)]
11+
pub struct LLMResponse { pub content: String }
12+
13+
pub struct EchoLLM;
14+
impl LLMAdapter for EchoLLM {
15+
fn infer(&self, request: LLMRequest) -> Result<LLMResponse> {
16+
Ok(LLMResponse { content: format!("echo: {}", request.prompt) })
17+
}
18+
}

aios-rs/src/memory.rs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
//! Memory subsystem mirroring Python base memory manager (simplified).
2+
use std::collections::HashMap;
3+
use std::time::{SystemTime, UNIX_EPOCH};
4+
5+
#[derive(Debug, Clone)]
6+
pub struct MemoryNote {
7+
pub id: String,
8+
pub content: String,
9+
pub keywords: Vec<String>,
10+
pub tags: Vec<String>,
11+
pub category: Option<String>,
12+
pub timestamp: u64,
13+
}
14+
15+
impl MemoryNote {
16+
pub fn new(id: impl Into<String>, content: impl Into<String>) -> Self {
17+
Self {
18+
id: id.into(),
19+
content: content.into(),
20+
keywords: vec![],
21+
tags: vec![],
22+
category: None,
23+
timestamp: SystemTime::now()
24+
.duration_since(UNIX_EPOCH)
25+
.unwrap()
26+
.as_secs(),
27+
}
28+
}
29+
}
30+
31+
#[derive(Debug, Clone)]
32+
pub struct MemoryQuery {
33+
pub operation: String,
34+
pub params: HashMap<String, String>,
35+
}
36+
37+
#[derive(Debug, Clone)]
38+
pub struct MemoryResponse {
39+
pub success: bool,
40+
pub memory_id: Option<String>,
41+
pub content: Option<String>,
42+
pub error: Option<String>,
43+
}
44+
45+
impl MemoryResponse {
46+
pub fn ok_id(id: impl Into<String>) -> Self { Self { success: true, memory_id: Some(id.into()), content: None, error: None } }
47+
pub fn ok_content(content: impl Into<String>) -> Self { Self { success: true, memory_id: None, content: Some(content.into()), error: None } }
48+
pub fn err(e: impl Into<String>) -> Self { Self { success: false, memory_id: None, content: None, error: Some(e.into()) } }
49+
}
50+
51+
pub trait MemoryManager: Send + Sync {
52+
fn add_memory(&mut self, note: MemoryNote) -> MemoryResponse;
53+
fn remove_memory(&mut self, id: &str) -> MemoryResponse;
54+
fn update_memory(&mut self, note: MemoryNote) -> MemoryResponse;
55+
fn get_memory(&self, id: &str) -> MemoryResponse;
56+
}
57+
58+
pub struct InMemoryMemoryManager {
59+
notes: HashMap<String, MemoryNote>,
60+
}
61+
62+
impl InMemoryMemoryManager { pub fn new() -> Self { Self { notes: HashMap::new() } } }
63+
64+
impl MemoryManager for InMemoryMemoryManager {
65+
fn add_memory(&mut self, note: MemoryNote) -> MemoryResponse {
66+
let id = note.id.clone();
67+
self.notes.insert(id.clone(), note);
68+
MemoryResponse::ok_id(id)
69+
}
70+
fn remove_memory(&mut self, id: &str) -> MemoryResponse {
71+
if self.notes.remove(id).is_some() { MemoryResponse::ok_id(id) } else { MemoryResponse::err("not found") }
72+
}
73+
fn update_memory(&mut self, note: MemoryNote) -> MemoryResponse {
74+
let id = note.id.clone();
75+
if self.notes.contains_key(&id) {
76+
self.notes.insert(id.clone(), note);
77+
MemoryResponse::ok_id(id)
78+
} else { MemoryResponse::err("not found") }
79+
}
80+
fn get_memory(&self, id: &str) -> MemoryResponse {
81+
self.notes.get(id).map(|n| MemoryResponse::ok_content(n.content.clone())).unwrap_or_else(|| MemoryResponse::err("not found"))
82+
}
83+
}

aios-rs/src/prelude.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//! Convenience prelude re-exporting primary traits & structs.
2+
pub use crate::context::{ContextManager, InMemoryContextManager};
3+
pub use crate::memory::{MemoryManager, InMemoryMemoryManager, MemoryNote, MemoryQuery, MemoryResponse};
4+
pub use crate::scheduler::{Scheduler, NoopScheduler};
5+
pub use crate::storage::{StorageManager, FsStorageManager};
6+
pub use crate::tool::{ToolManager, NoopToolManager};
7+
pub use crate::llm::{LLMAdapter, EchoLLM, LLMRequest, LLMResponse};

aios-rs/src/scheduler.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//! Scheduler trait (simplified placeholder).
2+
use crate::{LLMAdapter, MemoryManager, StorageManager, ToolManager};
3+
use std::sync::Arc;
4+
5+
pub trait Scheduler: Send + Sync {
6+
fn start(&mut self) -> anyhow::Result<()>;
7+
fn stop(&mut self) -> anyhow::Result<()>;
8+
}
9+
10+
pub struct NoopScheduler {
11+
pub llm: Arc<dyn LLMAdapter>,
12+
pub memory: Arc<std::sync::Mutex<dyn MemoryManager>>,
13+
pub storage: Arc<dyn StorageManager>,
14+
pub tool: Arc<dyn ToolManager>,
15+
running: bool,
16+
}
17+
18+
impl NoopScheduler {
19+
pub fn new(
20+
llm: Arc<dyn LLMAdapter>,
21+
memory: Arc<std::sync::Mutex<dyn MemoryManager>>,
22+
storage: Arc<dyn StorageManager>,
23+
tool: Arc<dyn ToolManager>,
24+
) -> Self { Self { llm, memory, storage, tool, running: false } }
25+
}
26+
27+
impl Scheduler for NoopScheduler {
28+
fn start(&mut self) -> anyhow::Result<()> { self.running = true; Ok(()) }
29+
fn stop(&mut self) -> anyhow::Result<()> { self.running = false; Ok(()) }
30+
}

0 commit comments

Comments
 (0)