feat: initial release — ZeroClaw v0.1.0
- 22 AI providers (OpenRouter, Anthropic, OpenAI, Mistral, etc.) - 7 channels (CLI, Telegram, Discord, Slack, iMessage, Matrix, Webhook) - 5-step onboarding wizard with Project Context personalization - OpenClaw-aligned system prompt (SOUL.md, IDENTITY.md, USER.md, AGENTS.md, etc.) - SQLite memory backend with auto-save - Skills system with on-demand loading - Security: autonomy levels, command allowlists, cost limits - 532 tests passing, 0 clippy warnings
This commit is contained in:
commit
05cb353f7f
71 changed files with 15757 additions and 0 deletions
71
src/runtime/mod.rs
Normal file
71
src/runtime/mod.rs
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
pub mod native;
|
||||
pub mod traits;
|
||||
|
||||
pub use native::NativeRuntime;
|
||||
pub use traits::RuntimeAdapter;
|
||||
|
||||
use crate::config::RuntimeConfig;
|
||||
|
||||
/// Factory: create the right runtime from config
|
||||
pub fn create_runtime(config: &RuntimeConfig) -> Box<dyn RuntimeAdapter> {
|
||||
match config.kind.as_str() {
|
||||
"native" | "docker" => Box::new(NativeRuntime::new()),
|
||||
"cloudflare" => {
|
||||
tracing::warn!("Cloudflare runtime not yet implemented, falling back to native");
|
||||
Box::new(NativeRuntime::new())
|
||||
}
|
||||
_ => {
|
||||
tracing::warn!("Unknown runtime '{}', falling back to native", config.kind);
|
||||
Box::new(NativeRuntime::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn factory_native() {
|
||||
let cfg = RuntimeConfig {
|
||||
kind: "native".into(),
|
||||
};
|
||||
let rt = create_runtime(&cfg);
|
||||
assert_eq!(rt.name(), "native");
|
||||
assert!(rt.has_shell_access());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn factory_docker_returns_native() {
|
||||
let cfg = RuntimeConfig {
|
||||
kind: "docker".into(),
|
||||
};
|
||||
let rt = create_runtime(&cfg);
|
||||
assert_eq!(rt.name(), "native");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn factory_cloudflare_falls_back() {
|
||||
let cfg = RuntimeConfig {
|
||||
kind: "cloudflare".into(),
|
||||
};
|
||||
let rt = create_runtime(&cfg);
|
||||
assert_eq!(rt.name(), "native");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn factory_unknown_falls_back() {
|
||||
let cfg = RuntimeConfig {
|
||||
kind: "wasm-edge-unknown".into(),
|
||||
};
|
||||
let rt = create_runtime(&cfg);
|
||||
assert_eq!(rt.name(), "native");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn factory_empty_falls_back() {
|
||||
let cfg = RuntimeConfig { kind: "".into() };
|
||||
let rt = create_runtime(&cfg);
|
||||
assert_eq!(rt.name(), "native");
|
||||
}
|
||||
}
|
||||
72
src/runtime/native.rs
Normal file
72
src/runtime/native.rs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
use super::traits::RuntimeAdapter;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Native runtime — full access, runs on Mac/Linux/Docker/Raspberry Pi
|
||||
pub struct NativeRuntime;
|
||||
|
||||
impl NativeRuntime {
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
impl RuntimeAdapter for NativeRuntime {
|
||||
fn name(&self) -> &str {
|
||||
"native"
|
||||
}
|
||||
|
||||
fn has_shell_access(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn has_filesystem_access(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn storage_path(&self) -> PathBuf {
|
||||
directories::UserDirs::new().map_or_else(
|
||||
|| PathBuf::from(".zeroclaw"),
|
||||
|u| u.home_dir().join(".zeroclaw"),
|
||||
)
|
||||
}
|
||||
|
||||
fn supports_long_running(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn native_name() {
|
||||
assert_eq!(NativeRuntime::new().name(), "native");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn native_has_shell_access() {
|
||||
assert!(NativeRuntime::new().has_shell_access());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn native_has_filesystem_access() {
|
||||
assert!(NativeRuntime::new().has_filesystem_access());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn native_supports_long_running() {
|
||||
assert!(NativeRuntime::new().supports_long_running());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn native_memory_budget_unlimited() {
|
||||
assert_eq!(NativeRuntime::new().memory_budget(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn native_storage_path_contains_zeroclaw() {
|
||||
let path = NativeRuntime::new().storage_path();
|
||||
assert!(path.to_string_lossy().contains("zeroclaw"));
|
||||
}
|
||||
}
|
||||
25
src/runtime/traits.rs
Normal file
25
src/runtime/traits.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
/// Runtime adapter — abstracts platform differences so the same agent
|
||||
/// code runs on native, Docker, Cloudflare Workers, Raspberry Pi, etc.
|
||||
pub trait RuntimeAdapter: Send + Sync {
|
||||
/// Human-readable runtime name
|
||||
fn name(&self) -> &str;
|
||||
|
||||
/// Whether this runtime supports shell access
|
||||
fn has_shell_access(&self) -> bool;
|
||||
|
||||
/// Whether this runtime supports filesystem access
|
||||
fn has_filesystem_access(&self) -> bool;
|
||||
|
||||
/// Base storage path for this runtime
|
||||
fn storage_path(&self) -> PathBuf;
|
||||
|
||||
/// Whether long-running processes (gateway, heartbeat) are supported
|
||||
fn supports_long_running(&self) -> bool;
|
||||
|
||||
/// Maximum memory budget in bytes (0 = unlimited)
|
||||
fn memory_budget(&self) -> u64 {
|
||||
0
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue