Documentation Index
Fetch the complete documentation index at: https://doc.ambientsoul.ai/llms.txt
Use this file to discover all available pages before exploring further.
Skill System
Skills extend Soul capabilities through a plugin architecture, enabling vision, voice, actuators, and custom behaviors.
Overview
The Skill System allows Souls to:
- Load capabilities dynamically
- Execute skills in isolated contexts
- Share data between skills safely
- Update skills without kernel changes
Architecture
Skill ABI (Application Binary Interface)
/// Core trait that all Skills must implement
pub trait Skill: Send + Sync {
/// Unique name of the skill
fn name(&self) -> &str;
/// Semantic version of the skill
fn version(&self) -> &str;
/// List of capabilities this skill provides
fn capabilities(&self) -> Vec<Capability>;
/// Execute the skill with given input
fn execute(&self, input: SkillInput) -> Result<SkillOutput, SkillError>;
/// Initialize the skill (optional)
fn initialize(&mut self) -> Result<(), SkillError> {
Ok(())
}
/// Shutdown the skill (optional)
fn shutdown(&mut self) -> Result<(), SkillError> {
Ok(())
}
}
Capability Types
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Capability {
TextProcessing,
ImageProcessing,
AudioProcessing,
VoiceSynthesis,
VisionAnalysis,
MotorControl,
DataStorage,
NetworkAccess,
Custom(String),
}
/// Input types that can be passed to skills
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SkillInput {
Text(String),
Image(Vec<u8>),
Audio(Vec<f32>),
Json(serde_json::Value),
Binary(Vec<u8>),
}
/// Output types that skills can return
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SkillOutput {
Text(String),
Image(Vec<u8>),
Audio(Vec<f32>),
Json(serde_json::Value),
Action(ActionCommand),
Binary(Vec<u8>),
}
/// Commands for actuator control
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ActionCommand {
pub target: String,
pub action: String,
pub parameters: serde_json::Value,
}
Error Handling
#[derive(Debug)]
pub enum SkillError {
InvalidInput(String),
ExecutionError(String),
NotImplemented(String),
ResourceUnavailable(String),
Custom(Box<dyn Error + Send + Sync>),
}
Creating a Skill
1. Basic Skill Structure
// hello_skill/src/lib.rs
use soul_kernel_skill_abi::{
export_skill, Capability, Skill, SkillError, SkillInput, SkillOutput,
};
pub struct HelloSkill {
greeting: String,
}
impl HelloSkill {
pub fn new() -> Self {
Self {
greeting: "Hello from Soul Kernel!".to_string(),
}
}
}
impl Skill for HelloSkill {
fn name(&self) -> &str {
"hello"
}
fn version(&self) -> &str {
env!("CARGO_PKG_VERSION")
}
fn capabilities(&self) -> Vec<Capability> {
vec![Capability::TextProcessing]
}
fn execute(&self, input: SkillInput) -> Result<SkillOutput, SkillError> {
match input {
SkillInput::Text(name) => {
let response = if name.is_empty() {
self.greeting.clone()
} else {
format!("{} Nice to meet you, {}!", self.greeting, name)
};
Ok(SkillOutput::Text(response))
}
_ => Err(SkillError::InvalidInput(
"Hello skill expects text input".to_string(),
)),
}
}
}
// Export the skill for dynamic loading
export_skill!(HelloSkill);
2. Skill Cargo.toml
[package]
name = "hello-skill"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[dependencies]
soul-kernel-skill-abi = { path = "../skill-abi" }
serde = { version = "1.0", features = ["derive"] }
3. Building & Loading
# Build as dynamic library
cargo build --release
# The skill will be available as a .dylib/.so/.dll file
ls target/release/libhello_skill.dylib
Skill Registry
The Soul Kernel provides a thread-safe skill registry for managing loaded skills:
use soul_kernel_core::SkillRegistry;
// Create registry
let registry = SkillRegistry::new();
// Load skill from dynamic library
let skill_id = registry.load_skill_from_library("./libhello_skill.dylib")?;
// Execute skill
let input = SkillInput::Text("Alice".to_string());
let output = registry.execute_skill(&skill_id, input)?;
// List loaded skills
for (name, version) in registry.list_skills() {
println!("Loaded: {} v{}", name, version);
}
// Unload skill when done
registry.unload_skill(&skill_id)?;
Built-in Example Skills
1. Hello Skill
Basic greeting skill demonstrating text processing.
2. Echo Skill
Multi-format skill that echoes any input type:
impl Skill for EchoSkill {
fn capabilities(&self) -> Vec<Capability> {
vec![
Capability::TextProcessing,
Capability::ImageProcessing,
Capability::AudioProcessing,
]
}
fn execute(&self, input: SkillInput) -> Result<SkillOutput, SkillError> {
// Echo skill simply returns the input unchanged
match input {
SkillInput::Text(text) => Ok(SkillOutput::Text(text)),
SkillInput::Image(data) => Ok(SkillOutput::Image(data)),
SkillInput::Audio(data) => Ok(SkillOutput::Audio(data)),
SkillInput::Json(json) => Ok(SkillOutput::Json(json)),
SkillInput::Binary(data) => Ok(SkillOutput::Binary(data)),
}
}
}
Skill Development Best Practices
- Thread Safety - Skills must be
Send + Sync
- Error Handling - Never panic, return proper errors
- Resource Management - Use
initialize() and shutdown()
- Clear Capabilities - Declare what your skill can do
- Version Carefully - Use semantic versioning
Security Considerations
- Skills run in the same process (sandboxing planned for future)
- Validate all inputs before processing
- Be careful with file system and network access
- Sign skills for authenticity (future feature)
Advanced Topics
Direct Skill Registration
For built-in skills that don’t need dynamic loading:
let skill = Box::new(MyBuiltInSkill::new());
let skill_id = registry.register_skill(skill);
Action Commands
Skills can return commands for physical actuators:
Ok(SkillOutput::Action(ActionCommand {
target: "arm".to_string(),
action: "wave".to_string(),
parameters: json!({
"duration": 2.0,
"amplitude": 0.5
}),
}))
Skill Composition (Future)
// Planned feature for composing multiple skills
let composite = SkillComposer::new()
.add("vision")
.add("language")
.add("voice")
.build();
Next Steps
Change Log
- 2025-06-12: Updated to reflect actual Skill ABI V1 implementation from Story-2
- Added complete trait definition with Send + Sync bounds
- Updated capability types to match implementation
- Added ActionCommand for actuator control
- Updated code examples to use actual API
- Added skill registry usage examples
- Clarified FFI-safe implementation details