soul-core
Async agentic runtime for Rust. Steerable agent loops, multi-provider LLM abstraction, semantic context management, virtual filesystem, and WASM-ready architecture.
What is this?
soul-core is the engine that powers autonomous agent loops. It provides everything needed to build LLM-powered agents that can reason, use tools, manage context, persist sessions, and run on native OS or in a browser via WASM.
use ;
use AnthropicProvider;
use ToolRegistry;
use *;
// Configure
let model = new;
let config = new;
let provider = new;
// Build
let tools = new;
let mut agent = new;
// Run
let = unbounded_channel;
let = unbounded_channel;
let options = RunOptions ;
let messages = agent.run.await?;
Architecture
| Module | Purpose |
|---|---|
agent |
Steerable agent loop with tool execution, compaction triggers, interruption |
provider |
Multi-provider LLM abstraction (Anthropic, OpenAI) with SSE streaming |
context |
Token-aware context window management with compaction and circuit breaker |
tool |
Async tool trait and registry |
hook |
Three-tier hook pipeline: modifying, void, persist |
permission |
Rule-based permission gate with glob patterns and risk levels |
cost |
Token/USD cost tracking with budget enforcement |
mcp |
Model Context Protocol client with JSON-RPC transport |
skill |
Config-driven tool definitions loaded from .skill/.md files |
executor |
Pluggable tool execution backends (shell, HTTP, MCP, LLM) |
session |
JSONL session persistence with lane serialization |
memory |
Hierarchical memory (MEMORY.md + topic files, bootstrap files) |
vfs |
Virtual filesystem: MemoryFs (WASM/tests), NativeFs (OS) |
vexec |
Virtual executor: MockExecutor (WASM/tests), NativeExecutor (OS) |
soullog |
Multi-sink structured logging |
subagent |
Subagent spawner for parallel task delegation |
semantic_recursion |
Context graph, TF-IDF search, symlinks, semantic fragmentation |
rlm |
Recursive Language Model engine (document search DSL) |
types |
Core types: Message, Role, ContentBlock, ToolDefinition, AgentConfig |
error |
Error types with thiserror |
Key Features
Agent Loop
The core AgentLoop runs a think-act-observe cycle: send messages to an LLM, execute any tool calls, feed results back, repeat until the LLM responds without tool calls or a budget/turn limit is hit.
- Real-time event streaming via
mpscchannels - Mid-loop steering (inject messages, interrupt)
- Automatic context compaction when approaching token limits
- Optional cost tracking and budget enforcement
Virtual Filesystem
All storage (sessions, memory, skills) goes through VirtualFs, a trait with two implementations:
NativeFs— real OS filesystem viatokio::fs(behindnativefeature)MemoryFs— in-memory BTreeMap (works everywhere, including WASM)
Custom implementations can target IndexedDB, S3, or anything else.
Virtual Executor
Shell commands go through VirtualExecutor:
NativeExecutor— real subprocesses viatokio::process(behindnativefeature)MockExecutor— canned responses for testingNoopExecutor— returns error (for WASM environments)
Skills
Define tools as .skill or .md files with YAML frontmatter:
name: search_codebase
description: Search for a pattern
input_schema:
type: object
properties:
required: [pattern]
execution:
type: shell
command_template: "rg '{{pattern}}' --json"
timeout_secs: 30
Search the codebase using ripgrep.
Load and register as tools:
let loader = new;
loader.load_all.await?;
loader.register_all_as_tools;
Hook Pipeline
Three tiers of hooks modify agent behavior without changing the loop:
- Modifying hooks — run sequentially, can alter or cancel operations (permission checks, prompt injection)
- Void hooks — run in parallel, fire-and-forget (logging, metrics)
- Persist hooks — synchronous transforms on the hot path (redaction, storage)
Semantic Context Management
The semantic_recursion module implements a social graph for LLM context:
- Graph nodes for every piece of context (requests, responses, tool calls, compactions)
- Symlinks replace messages with 6-char hash references that LLMs can resolve
- Semantic fragmentation splits long messages into clusters via agglomerative clustering on TF-IDF embeddings
- Token-budgeted retrieval combines keyword relevance, vector similarity, and graph neighbor expansion
Permission System
Rule-based permission gate with glob patterns:
let mut manager = new;
manager
.add_rule
.add_rule
.classify_risk;
Cost Tracking
Per-turn token counting with model-specific pricing and budget enforcement:
let tracker = new;
let enforcer = new;
let agent = new
.with_cost_tracker
.with_budget;
MCP Client
Connect to Model Context Protocol servers and expose their tools:
let transport = new;
let mut client = new;
client.initialize.await?;
client.register_tools.await?;
WASM Support
The library compiles to WebAssembly. Use --no-default-features --features wasm:
[]
= { = "0.5", = false, = ["wasm"] }
In WASM mode:
MemoryFsreplacesNativeFsNoopExecutorreplacesNativeExecutorreqwestuses fetch APIuuidusesjsfeature for browser crypto
Installation
# Native (default) — full OS support
[]
= "0.5"
# WASM — browser target
[]
= { = "0.5", = false, = ["wasm"] }
# Minimal — no runtime, no filesystem
[]
= { = "0.5", = false }
Testing
License
MIT