From 78ee19409a3eb2e84bb15a06a4480c372ecd5214 Mon Sep 17 00:00:00 2001 From: nullmonk Date: Sat, 17 Jan 2026 14:28:21 -0500 Subject: [PATCH 1/4] feat(eldritchv2): add libcache for thread-safe cross-interpreter caching --- implants/Cargo.toml | 2 + implants/lib/eldritchv2/eldritchv2/Cargo.toml | 4 ++ implants/lib/eldritchv2/eldritchv2/src/lib.rs | 4 ++ .../stdlib/eldritch-libcache/Cargo.toml | 14 ++++++ .../stdlib/eldritch-libcache/src/lib.rs | 46 +++++++++++++++++++ .../stdlib/eldritch-libcache/src/std.rs | 36 +++++++++++++++ .../lib/eldritchv2/stdlib/tests/src/lib.rs | 44 ++++++++++++++++++ 7 files changed, 150 insertions(+) create mode 100644 implants/lib/eldritchv2/stdlib/eldritch-libcache/Cargo.toml create mode 100644 implants/lib/eldritchv2/stdlib/eldritch-libcache/src/lib.rs create mode 100644 implants/lib/eldritchv2/stdlib/eldritch-libcache/src/std.rs diff --git a/implants/Cargo.toml b/implants/Cargo.toml index fe3302bab..4837e5d8a 100644 --- a/implants/Cargo.toml +++ b/implants/Cargo.toml @@ -25,6 +25,7 @@ members = [ "lib/eldritchv2/stdlib/eldritch-libreport", "lib/eldritchv2/stdlib/eldritch-libsys", "lib/eldritchv2/stdlib/eldritch-libtime", + "lib/eldritchv2/stdlib/eldritch-libcache", "lib/eldritchv2/stdlib/tests", "lib/eldritchv2/stdlib/migration", "lib/eldritchv2/eldritchv2", @@ -47,6 +48,7 @@ eldritchv2 = {path = "lib/eldritchv2/eldritchv2", default-features = false} eldritch-agent = {path = "lib/eldritchv2/eldritch-agent"} eldritch-libagent = {path = "lib/eldritchv2/stdlib/eldritch-libagent", default-features = false} eldritch-libassets = {path = "lib/eldritchv2/stdlib/eldritch-libassets", default-features = false} +eldritch-libcache = {path = "lib/eldritchv2/stdlib/eldritch-libcache", default-features = false} eldritch-libcrypto = {path = "lib/eldritchv2/stdlib/eldritch-libcrypto",default-features = false } eldritch-libfile = {path = "lib/eldritchv2/stdlib/eldritch-libfile",default-features = false } eldritch-libhttp = {path = "lib/eldritchv2/stdlib/eldritch-libhttp",default-features = false } diff --git a/implants/lib/eldritchv2/eldritchv2/Cargo.toml b/implants/lib/eldritchv2/eldritchv2/Cargo.toml index b52fb31e8..29018b1fe 100644 --- a/implants/lib/eldritchv2/eldritchv2/Cargo.toml +++ b/implants/lib/eldritchv2/eldritchv2/Cargo.toml @@ -22,6 +22,7 @@ eldritch-libregex = { workspace = true, default-features = false } eldritch-libreport = { workspace = true, default-features = false } eldritch-libsys = { workspace = true, default-features = false } eldritch-libtime = { workspace = true, default-features = false } +eldritch-libcache = { workspace = true, default-features = false } pb = { workspace = true } eldritch-repl = { workspace = true, default-features = false } @@ -41,6 +42,7 @@ fake_bindings = [ "fake_report", "fake_sys", "fake_time", + "fake_cache", ] fake_agent = ["eldritch-libagent/fake_bindings"] fake_assets = ["eldritch-libassets/fake_bindings"] @@ -54,6 +56,7 @@ fake_regex = ["eldritch-libregex/fake_bindings"] fake_report = ["eldritch-libreport/fake_bindings"] fake_sys = ["eldritch-libsys/fake_bindings"] fake_time = ["eldritch-libtime/fake_bindings"] +fake_cache = ["eldritch-libcache/fake_bindings"] stdlib = [ "eldritch-libagent/stdlib", "eldritch-libassets/stdlib", @@ -67,6 +70,7 @@ stdlib = [ "eldritch-libreport/stdlib", "eldritch-libsys/stdlib", "eldritch-libtime/stdlib", + "eldritch-libcache/stdlib", ] [dev-dependencies] diff --git a/implants/lib/eldritchv2/eldritchv2/src/lib.rs b/implants/lib/eldritchv2/eldritchv2/src/lib.rs index 890f89912..b70b033ad 100644 --- a/implants/lib/eldritchv2/eldritchv2/src/lib.rs +++ b/implants/lib/eldritchv2/eldritchv2/src/lib.rs @@ -18,6 +18,7 @@ pub use eldritch_libregex as regex; pub use eldritch_libreport as report; pub use eldritch_libsys as sys; pub use eldritch_libtime as time; +pub use eldritch_libcache as cache; pub use eldritch_repl as repl; // Re-export core types @@ -46,6 +47,8 @@ pub use crate::assets::std::EmptyAssets; #[cfg(feature = "stdlib")] use crate::assets::std::StdAssetsLibrary; #[cfg(feature = "stdlib")] +use crate::cache::std::StdCacheLibrary; +#[cfg(feature = "stdlib")] use crate::crypto::std::StdCryptoLibrary; #[cfg(feature = "stdlib")] use crate::file::std::StdFileLibrary; @@ -117,6 +120,7 @@ impl Interpreter { pub fn with_default_libs(mut self) -> Self { #[cfg(feature = "stdlib")] { + self.inner.register_lib(StdCacheLibrary); self.inner.register_lib(StdCryptoLibrary); self.inner.register_lib(StdFileLibrary); self.inner.register_lib(StdHttpLibrary); diff --git a/implants/lib/eldritchv2/stdlib/eldritch-libcache/Cargo.toml b/implants/lib/eldritchv2/stdlib/eldritch-libcache/Cargo.toml new file mode 100644 index 000000000..8b92122e1 --- /dev/null +++ b/implants/lib/eldritchv2/stdlib/eldritch-libcache/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "eldritch-libcache" +version = "0.1.0" +edition = "2024" + +[dependencies] +eldritch-core = { workspace = true } +eldritch-macros = { workspace = true } +spin = { workspace = true, features = ["mutex"] } + +[features] +default = ["stdlib"] +stdlib = [] +fake_bindings = [] diff --git a/implants/lib/eldritchv2/stdlib/eldritch-libcache/src/lib.rs b/implants/lib/eldritchv2/stdlib/eldritch-libcache/src/lib.rs new file mode 100644 index 000000000..f54381e5a --- /dev/null +++ b/implants/lib/eldritchv2/stdlib/eldritch-libcache/src/lib.rs @@ -0,0 +1,46 @@ +#![allow(clippy::mutable_key_type)] +#![allow(unexpected_cfgs)] +extern crate alloc; + +use alloc::string::String; +use eldritch_core::Value; +use eldritch_macros::{eldritch_library, eldritch_method}; + +#[cfg(feature = "stdlib")] +pub mod std; + +#[eldritch_library("cache")] +/// The `cache` library provides a thread-safe in-memory cache shared across interpreters. +pub trait CacheLibrary { + #[eldritch_method] + /// Retrieves a value from the cache. + /// + /// **Parameters** + /// - `key` (`str`): The key to look up. + /// + /// **Returns** + /// - `Value`: The value if found, or `Null` (or undefined behavior depending on caller, but returns Value). + /// Actually, eldritch `Value` usually has a `Null` variant or we can return `Value::Null` equivalent. + fn get(&self, key: String) -> Result; + + #[eldritch_method] + /// Sets a value in the cache. + /// + /// **Parameters** + /// - `key` (`str`): The key to set. + /// - `val` (`Value`): The value to store. + /// + /// **Returns** + /// - `None` + fn set(&self, key: String, val: Value) -> Result<(), String>; + + #[eldritch_method] + /// Deletes a value from the cache. + /// + /// **Parameters** + /// - `key` (`str`): The key to remove. + /// + /// **Returns** + /// - `Value`: The removed value, or error/null if not found. + fn delete(&self, key: String) -> Result; +} diff --git a/implants/lib/eldritchv2/stdlib/eldritch-libcache/src/std.rs b/implants/lib/eldritchv2/stdlib/eldritch-libcache/src/std.rs new file mode 100644 index 000000000..a15be7fda --- /dev/null +++ b/implants/lib/eldritchv2/stdlib/eldritch-libcache/src/std.rs @@ -0,0 +1,36 @@ +use crate::CacheLibrary; +use alloc::collections::BTreeMap; +use alloc::string::String; +use eldritch_core::Value; +use eldritch_macros::eldritch_library_impl; +use spin::Mutex; + +static CACHE: Mutex> = Mutex::new(BTreeMap::new()); + +#[derive(Debug)] +#[eldritch_library_impl(CacheLibrary)] +pub struct StdCacheLibrary; + +impl CacheLibrary for StdCacheLibrary { + fn get(&self, key: String) -> Result { + let guard = CACHE.lock(); + match guard.get(&key) { + Some(v) => Ok(v.clone()), + None => Ok(Value::None), + } + } + + fn set(&self, key: String, val: Value) -> Result<(), String> { + let mut guard = CACHE.lock(); + guard.insert(key, val); + Ok(()) + } + + fn delete(&self, key: String) -> Result { + let mut guard = CACHE.lock(); + match guard.remove(&key) { + Some(v) => Ok(v), + None => Ok(Value::None), + } + } +} \ No newline at end of file diff --git a/implants/lib/eldritchv2/stdlib/tests/src/lib.rs b/implants/lib/eldritchv2/stdlib/tests/src/lib.rs index f86e18581..8f2440f48 100644 --- a/implants/lib/eldritchv2/stdlib/tests/src/lib.rs +++ b/implants/lib/eldritchv2/stdlib/tests/src/lib.rs @@ -39,6 +39,50 @@ mod tests { interp.register_lib(eldritchv2::random::std::StdRandomLibrary); interp.register_lib(eldritchv2::regex::std::StdRegexLibrary); interp.register_lib(eldritchv2::time::std::StdTimeLibrary); + interp.register_lib(eldritchv2::cache::std::StdCacheLibrary); + } + + #[test] + fn test_cache_library() -> Result<()> { + let mut interp1 = Interpreter::new(); + interp1.register_lib(eldritchv2::cache::std::StdCacheLibrary); + + let code1 = r#" +cache.set("foo", "bar") +return cache.get("foo") +"#; + + let res1 = interp1.interpret(code1).map_err(|e| anyhow::anyhow!(e))?; + if let Value::String(s) = res1 { + assert_eq!(s, "bar"); + } else { + panic!("Expected string 'bar', got {:?}", res1); + } + + // Test shared state across interpreters + let mut interp2 = Interpreter::new(); + interp2.register_lib(eldritchv2::cache::std::StdCacheLibrary); + + let code2 = r#" +return cache.get("foo") +"#; + + let res2 = interp2.interpret(code2).map_err(|e| anyhow::anyhow!(e))?; + if let Value::String(s) = res2 { + assert_eq!(s, "bar"); + } else { + panic!("Expected string 'bar' in interp2, got {:?}", res2); + } + + // Test delete + let code3 = r#" +cache.delete("foo") +return cache.get("foo") +"#; + let res3 = interp2.interpret(code3).map_err(|e| anyhow::anyhow!(e))?; + assert!(matches!(res3, Value::None)); + + Ok(()) } #[test] From 6e594a704a23f47228c0d4d30d670dfac83e1360 Mon Sep 17 00:00:00 2001 From: nullmonk Date: Sat, 17 Jan 2026 14:38:04 -0500 Subject: [PATCH 2/4] refactor(eldritchv2): move cache state from global static to struct field --- implants/lib/eldritchv2/eldritchv2/src/lib.rs | 2 +- .../stdlib/eldritch-libcache/src/std.rs | 31 ++++++++++++++----- .../lib/eldritchv2/stdlib/tests/src/lib.rs | 11 +++++-- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/implants/lib/eldritchv2/eldritchv2/src/lib.rs b/implants/lib/eldritchv2/eldritchv2/src/lib.rs index b70b033ad..1e2270b5d 100644 --- a/implants/lib/eldritchv2/eldritchv2/src/lib.rs +++ b/implants/lib/eldritchv2/eldritchv2/src/lib.rs @@ -120,7 +120,7 @@ impl Interpreter { pub fn with_default_libs(mut self) -> Self { #[cfg(feature = "stdlib")] { - self.inner.register_lib(StdCacheLibrary); + self.inner.register_lib(StdCacheLibrary::new()); self.inner.register_lib(StdCryptoLibrary); self.inner.register_lib(StdFileLibrary); self.inner.register_lib(StdHttpLibrary); diff --git a/implants/lib/eldritchv2/stdlib/eldritch-libcache/src/std.rs b/implants/lib/eldritchv2/stdlib/eldritch-libcache/src/std.rs index a15be7fda..5be83ba62 100644 --- a/implants/lib/eldritchv2/stdlib/eldritch-libcache/src/std.rs +++ b/implants/lib/eldritchv2/stdlib/eldritch-libcache/src/std.rs @@ -1,19 +1,34 @@ use crate::CacheLibrary; use alloc::collections::BTreeMap; use alloc::string::String; +use alloc::sync::Arc; use eldritch_core::Value; use eldritch_macros::eldritch_library_impl; use spin::Mutex; -static CACHE: Mutex> = Mutex::new(BTreeMap::new()); - -#[derive(Debug)] +#[derive(Debug, Clone)] #[eldritch_library_impl(CacheLibrary)] -pub struct StdCacheLibrary; +pub struct StdCacheLibrary { + store: Arc>>, +} + +impl Default for StdCacheLibrary { + fn default() -> Self { + Self { + store: Arc::new(Mutex::new(BTreeMap::new())), + } + } +} + +impl StdCacheLibrary { + pub fn new() -> Self { + Self::default() + } +} impl CacheLibrary for StdCacheLibrary { fn get(&self, key: String) -> Result { - let guard = CACHE.lock(); + let guard = self.store.lock(); match guard.get(&key) { Some(v) => Ok(v.clone()), None => Ok(Value::None), @@ -21,16 +36,16 @@ impl CacheLibrary for StdCacheLibrary { } fn set(&self, key: String, val: Value) -> Result<(), String> { - let mut guard = CACHE.lock(); + let mut guard = self.store.lock(); guard.insert(key, val); Ok(()) } fn delete(&self, key: String) -> Result { - let mut guard = CACHE.lock(); + let mut guard = self.store.lock(); match guard.remove(&key) { Some(v) => Ok(v), None => Ok(Value::None), } } -} \ No newline at end of file +} diff --git a/implants/lib/eldritchv2/stdlib/tests/src/lib.rs b/implants/lib/eldritchv2/stdlib/tests/src/lib.rs index 8f2440f48..43580b203 100644 --- a/implants/lib/eldritchv2/stdlib/tests/src/lib.rs +++ b/implants/lib/eldritchv2/stdlib/tests/src/lib.rs @@ -39,13 +39,17 @@ mod tests { interp.register_lib(eldritchv2::random::std::StdRandomLibrary); interp.register_lib(eldritchv2::regex::std::StdRegexLibrary); interp.register_lib(eldritchv2::time::std::StdTimeLibrary); - interp.register_lib(eldritchv2::cache::std::StdCacheLibrary); + interp.register_lib(eldritchv2::cache::std::StdCacheLibrary::new()); } #[test] fn test_cache_library() -> Result<()> { + // Create a shared cache library instance + let cache_lib = eldritchv2::cache::std::StdCacheLibrary::new(); + let mut interp1 = Interpreter::new(); - interp1.register_lib(eldritchv2::cache::std::StdCacheLibrary); + // Register the shared instance (assuming StdCacheLibrary is Clone and shares state internally via Arc) + interp1.register_lib(cache_lib.clone()); let code1 = r#" cache.set("foo", "bar") @@ -61,7 +65,8 @@ return cache.get("foo") // Test shared state across interpreters let mut interp2 = Interpreter::new(); - interp2.register_lib(eldritchv2::cache::std::StdCacheLibrary); + // Register the SAME cache instance + interp2.register_lib(cache_lib); let code2 = r#" return cache.get("foo") From 8d5323a56d22a0ec4243fa8410ed9c5e4c403755 Mon Sep 17 00:00:00 2001 From: nullmonk Date: Sat, 17 Jan 2026 15:04:04 -0500 Subject: [PATCH 3/4] Add cache and implement in golem --- implants/golemv2/src/main.rs | 11 +++++--- .../stdlib/eldritch-libassets/src/std/mod.rs | 1 + .../stdlib/eldritch-libcache/src/std.rs | 2 +- .../lib/eldritchv2/stdlib/tests/Cargo.toml | 1 + .../lib/eldritchv2/stdlib/tests/src/lib.rs | 26 +++++++++++++++++++ 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/implants/golemv2/src/main.rs b/implants/golemv2/src/main.rs index aa55289ad..fe89549bd 100644 --- a/implants/golemv2/src/main.rs +++ b/implants/golemv2/src/main.rs @@ -7,6 +7,7 @@ use eldritchv2::assets::{ AssetsLibrary, std::{EmbeddedAssets, StdAssetsLibrary}, }; +use eldritchv2::cache::std::StdCacheLibrary; use eldritchv2::conversion::ToValue; use eldritchv2::{ForeignValue, Interpreter, StdoutPrinter}; use pb::c2::TaskContext; @@ -36,7 +37,7 @@ pub struct ParsedTome { } // Build a new runtime -fn new_runtime(assetlib: impl ForeignValue + 'static) -> Interpreter { +fn new_runtime(assetlib: impl ForeignValue + 'static, cache_lib: StdCacheLibrary) -> Interpreter { // Maybe change the printer here? let mut interp = Interpreter::new_with_printer(Arc::new(StdoutPrinter)).with_default_libs(); // Register the libraries that we need. Basically the same as interp.with_task_context but @@ -55,6 +56,7 @@ fn new_runtime(assetlib: impl ForeignValue + 'static) -> Interpreter { eldritchv2::pivot::std::StdPivotLibrary::new(agent.clone(), task_context.clone()); interp.register_lib(pivot_lib); interp.register_lib(assetlib); + interp.register_lib(cache_lib); interp } @@ -158,16 +160,17 @@ fn main() -> anyhow::Result<()> { } } - // Setup the interpreter. This will need refactored when we do multi-threaded - let mut interp = new_runtime(locker); + let cache_lib = StdCacheLibrary::new(); if matches.contains_id("interactive") { + let interp = new_runtime(locker.clone(), cache_lib); repl::repl(interp)?; return Ok(()); } // Print a debug for the configured assets and tomes if matches.get_flag("dump") { + let mut interp = new_runtime(locker.clone(), cache_lib.clone()); let tome_names: Vec<&str> = parsed_tomes.iter().map(|tome| tome.name.as_str()).collect(); println!("tomes = {:?}", tome_names); match interp.interpret("print(\"assets =\", assets.list())") { @@ -177,10 +180,12 @@ fn main() -> anyhow::Result<()> { exit(127); } } + return Ok(()); } // Time to run some commands for tome in parsed_tomes { + let mut interp = new_runtime(locker.clone(), cache_lib.clone()); // In the future we would like to set input params here. // We could compile them in for the default dropper assets let params: BTreeMap = BTreeMap::new(); diff --git a/implants/lib/eldritchv2/stdlib/eldritch-libassets/src/std/mod.rs b/implants/lib/eldritchv2/stdlib/eldritch-libassets/src/std/mod.rs index cce5e94a9..a7f30125a 100644 --- a/implants/lib/eldritchv2/stdlib/eldritch-libassets/src/std/mod.rs +++ b/implants/lib/eldritchv2/stdlib/eldritch-libassets/src/std/mod.rs @@ -104,6 +104,7 @@ impl AssetBackend for AgentAssets { } } +#[derive(Clone)] #[eldritch_library_impl(AssetsLibrary)] pub struct StdAssetsLibrary { // Stores a vector of boxed trait objects for runtime polymorphism. diff --git a/implants/lib/eldritchv2/stdlib/eldritch-libcache/src/std.rs b/implants/lib/eldritchv2/stdlib/eldritch-libcache/src/std.rs index 5be83ba62..2dc8c05a4 100644 --- a/implants/lib/eldritchv2/stdlib/eldritch-libcache/src/std.rs +++ b/implants/lib/eldritchv2/stdlib/eldritch-libcache/src/std.rs @@ -48,4 +48,4 @@ impl CacheLibrary for StdCacheLibrary { None => Ok(Value::None), } } -} +} \ No newline at end of file diff --git a/implants/lib/eldritchv2/stdlib/tests/Cargo.toml b/implants/lib/eldritchv2/stdlib/tests/Cargo.toml index 6a719e3ab..adde8b52a 100644 --- a/implants/lib/eldritchv2/stdlib/tests/Cargo.toml +++ b/implants/lib/eldritchv2/stdlib/tests/Cargo.toml @@ -12,3 +12,4 @@ serde = { workspace = true, features = ["derive"] } serde_yaml = {workspace = true} spin = { version = "0.10.0", features = ["rwlock"] } log = { workspace = true } +uuid = { workspace = true, features = ["v4"] } diff --git a/implants/lib/eldritchv2/stdlib/tests/src/lib.rs b/implants/lib/eldritchv2/stdlib/tests/src/lib.rs index 43580b203..66cb84bde 100644 --- a/implants/lib/eldritchv2/stdlib/tests/src/lib.rs +++ b/implants/lib/eldritchv2/stdlib/tests/src/lib.rs @@ -90,6 +90,32 @@ return cache.get("foo") Ok(()) } + #[test] + fn test_cache_sharing_random() -> Result<()> { + let cache_lib = eldritchv2::cache::std::StdCacheLibrary::new(); + let random_val = uuid::Uuid::new_v4().to_string(); + + let mut interp1 = Interpreter::new(); + interp1.register_lib(cache_lib.clone()); + + let code1 = format!("cache.set('key', '{}')", random_val); + interp1.interpret(&code1).map_err(|e| anyhow::anyhow!(e))?; + + let mut interp2 = Interpreter::new(); + interp2.register_lib(cache_lib); + + let code2 = "return cache.get('key')"; + let res = interp2.interpret(code2).map_err(|e| anyhow::anyhow!(e))?; + + if let Value::String(s) = res { + assert_eq!(s, random_val); + } else { + panic!("Expected string {}, got {:?}", random_val, res); + } + + Ok(()) + } + #[test] fn test_all_tomes() -> Result<()> { let manifest_dir = std::env::var("CARGO_MANIFEST_DIR")?; From 07f12ed0257d380555a59b101c9e5638ecd63cab Mon Sep 17 00:00:00 2001 From: nullmonk Date: Sat, 17 Jan 2026 15:12:40 -0500 Subject: [PATCH 4/4] Add cache to eldritch --- implants/imixv2/src/task.rs | 17 +++++++++++++++-- implants/lib/eldritchv2/eldritchv2/src/lib.rs | 2 +- .../stdlib/eldritch-libcache/src/std.rs | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/implants/imixv2/src/task.rs b/implants/imixv2/src/task.rs index 73495cd87..fd9972be3 100644 --- a/implants/imixv2/src/task.rs +++ b/implants/imixv2/src/task.rs @@ -5,6 +5,7 @@ use std::time::SystemTime; use eldritchv2::agent::agent::Agent; use eldritchv2::assets::std::EmbeddedAssets; +use eldritchv2::cache::std::StdCacheLibrary; use eldritchv2::{Interpreter, Printer, Span, Value, conversion::ToValue}; use pb::c2::{ReportTaskOutputRequest, Task, TaskContext, TaskError, TaskOutput}; use prost_types::Timestamp; @@ -46,6 +47,7 @@ struct TaskHandle { #[derive(Clone)] pub struct TaskRegistry { tasks: Arc>>, + cache_lib: StdCacheLibrary, } impl Default for TaskRegistry { @@ -58,6 +60,7 @@ impl TaskRegistry { pub fn new() -> Self { Self { tasks: Arc::new(Mutex::new(BTreeMap::new())), + cache_lib: StdCacheLibrary::new(), } } @@ -74,6 +77,7 @@ impl TaskRegistry { } let tasks_registry = self.tasks.clone(); + let cache_lib = self.cache_lib.clone(); // Capture runtime handle to spawn streaming task let runtime_handle = tokio::runtime::Handle::current(); @@ -83,7 +87,7 @@ impl TaskRegistry { thread::spawn(move || { if let Some(tome) = task.tome { - execute_task(task_context.clone(), tome, agent, runtime_handle); + execute_task(task_context.clone(), tome, agent, runtime_handle, cache_lib); } else { #[cfg(debug_assertions)] log::warn!("Task {0} has no tome", task_context.clone().task_id); @@ -165,11 +169,18 @@ fn execute_task( tome: pb::eldritch::Tome, agent: Arc, runtime_handle: tokio::runtime::Handle, + cache_lib: StdCacheLibrary, ) { // Setup StreamPrinter and Interpreter let (tx, rx) = mpsc::unbounded_channel(); let printer = Arc::new(StreamPrinter::new(tx)); - let mut interp = setup_interpreter(task_context.clone(), &tome, agent.clone(), printer.clone()); + let mut interp = setup_interpreter( + task_context.clone(), + &tome, + agent.clone(), + printer.clone(), + cache_lib, + ); // Report Start report_start(task_context.clone(), &agent); @@ -217,8 +228,10 @@ fn setup_interpreter( tome: &pb::eldritch::Tome, agent: Arc, printer: Arc, + cache_lib: StdCacheLibrary, ) -> Interpreter { let mut interp = Interpreter::new_with_printer(printer).with_default_libs(); + interp.register_lib(cache_lib); // Remote asset filenames let remote_assets = tome.file_names.clone(); diff --git a/implants/lib/eldritchv2/eldritchv2/src/lib.rs b/implants/lib/eldritchv2/eldritchv2/src/lib.rs index 1e2270b5d..b17afaadd 100644 --- a/implants/lib/eldritchv2/eldritchv2/src/lib.rs +++ b/implants/lib/eldritchv2/eldritchv2/src/lib.rs @@ -8,6 +8,7 @@ extern crate std; // Re-exports from eldritch-stdlib pub use eldritch_libagent as agent; pub use eldritch_libassets as assets; +pub use eldritch_libcache as cache; pub use eldritch_libcrypto as crypto; pub use eldritch_libfile as file; pub use eldritch_libhttp as http; @@ -18,7 +19,6 @@ pub use eldritch_libregex as regex; pub use eldritch_libreport as report; pub use eldritch_libsys as sys; pub use eldritch_libtime as time; -pub use eldritch_libcache as cache; pub use eldritch_repl as repl; // Re-export core types diff --git a/implants/lib/eldritchv2/stdlib/eldritch-libcache/src/std.rs b/implants/lib/eldritchv2/stdlib/eldritch-libcache/src/std.rs index 2dc8c05a4..5be83ba62 100644 --- a/implants/lib/eldritchv2/stdlib/eldritch-libcache/src/std.rs +++ b/implants/lib/eldritchv2/stdlib/eldritch-libcache/src/std.rs @@ -48,4 +48,4 @@ impl CacheLibrary for StdCacheLibrary { None => Ok(Value::None), } } -} \ No newline at end of file +}