Merge branch 'main' of git.ourworld.tf:herocode/actor_osis
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
target
|
target
|
||||||
|
logs
|
16
Cargo.lock
generated
16
Cargo.lock
generated
@@ -6,6 +6,7 @@ version = 4
|
|||||||
name = "actor_osis"
|
name = "actor_osis"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"baobab_actor",
|
"baobab_actor",
|
||||||
"chrono",
|
"chrono",
|
||||||
@@ -192,11 +193,13 @@ dependencies = [
|
|||||||
name = "baobab_actor"
|
name = "baobab_actor"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
|
"crossterm",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"hero_job",
|
"hero_job",
|
||||||
"hero_supervisor",
|
"hero_supervisor",
|
||||||
@@ -205,6 +208,7 @@ dependencies = [
|
|||||||
"heromodels_core",
|
"heromodels_core",
|
||||||
"log",
|
"log",
|
||||||
"ratatui",
|
"ratatui",
|
||||||
|
"ratatui",
|
||||||
"redis",
|
"redis",
|
||||||
"rhai",
|
"rhai",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -340,8 +344,10 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.43"
|
version = "4.5.43"
|
||||||
|
version = "4.5.43"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "50fd97c9dc2399518aa331917ac6f274280ec5eb34e555dd291899745c48ec6f"
|
checksum = "50fd97c9dc2399518aa331917ac6f274280ec5eb34e555dd291899745c48ec6f"
|
||||||
|
checksum = "50fd97c9dc2399518aa331917ac6f274280ec5eb34e555dd291899745c48ec6f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
@@ -350,8 +356,10 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_builder"
|
name = "clap_builder"
|
||||||
version = "4.5.43"
|
version = "4.5.43"
|
||||||
|
version = "4.5.43"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c35b5830294e1fa0462034af85cc95225a4cb07092c088c55bda3147cfcd8f65"
|
checksum = "c35b5830294e1fa0462034af85cc95225a4cb07092c088c55bda3147cfcd8f65"
|
||||||
|
checksum = "c35b5830294e1fa0462034af85cc95225a4cb07092c088c55bda3147cfcd8f65"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
"anstyle",
|
"anstyle",
|
||||||
@@ -390,7 +398,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
|
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -938,8 +946,10 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "h2"
|
name = "h2"
|
||||||
version = "0.4.12"
|
version = "0.4.12"
|
||||||
|
version = "0.4.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386"
|
checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386"
|
||||||
|
checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atomic-waker",
|
"atomic-waker",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -1189,6 +1199,7 @@ dependencies = [
|
|||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"h2 0.4.12",
|
"h2 0.4.12",
|
||||||
|
"h2 0.4.12",
|
||||||
"http 1.3.1",
|
"http 1.3.1",
|
||||||
"http-body 1.0.1",
|
"http-body 1.0.1",
|
||||||
"httparse",
|
"httparse",
|
||||||
@@ -2460,6 +2471,7 @@ dependencies = [
|
|||||||
name = "reth-ipc"
|
name = "reth-ipc"
|
||||||
version = "1.6.0"
|
version = "1.6.0"
|
||||||
source = "git+https://github.com/paradigmxyz/reth#59e4a5556fa54f1c210e45412b6a91f2351bea19"
|
source = "git+https://github.com/paradigmxyz/reth#59e4a5556fa54f1c210e45412b6a91f2351bea19"
|
||||||
|
source = "git+https://github.com/paradigmxyz/reth#59e4a5556fa54f1c210e45412b6a91f2351bea19"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures",
|
"futures",
|
||||||
@@ -3821,7 +3833,7 @@ version = "0.1.9"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@@ -9,7 +9,11 @@ path = "src/lib.rs"
|
|||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "actor_osis"
|
name = "actor_osis"
|
||||||
path = "cmd/actor_osis.rs"
|
path = "cmd/actor.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "actor_osis_tui"
|
||||||
|
path = "cmd/terminal_ui.rs"
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "engine"
|
name = "engine"
|
||||||
@@ -22,6 +26,7 @@ path = "examples/actor.rs"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
anyhow = "1.0"
|
||||||
redis = { version = "0.25.0", features = ["tokio-comp"] }
|
redis = { version = "0.25.0", features = ["tokio-comp"] }
|
||||||
rhai = { version = "1.21.0", features = ["std", "sync", "decimal", "internals"] }
|
rhai = { version = "1.21.0", features = ["std", "sync", "decimal", "internals"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
148
cmd/terminal_ui.rs
Normal file
148
cmd/terminal_ui.rs
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
//! Simplified main function for Baobab Actor TUI
|
||||||
|
//!
|
||||||
|
//! This binary provides a clean entry point for the actor monitoring and job dispatch interface.
|
||||||
|
|
||||||
|
use anyhow::{Result, Context};
|
||||||
|
use baobab_actor::terminal_ui::{App, setup_and_run_tui};
|
||||||
|
use clap::Parser;
|
||||||
|
use log::{info, warn, error};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::process::{Child, Command};
|
||||||
|
use tokio::signal;
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[command(name = "baobab-actor-tui")]
|
||||||
|
#[command(about = "Terminal UI for Baobab Actor - Monitor and dispatch jobs to a single actor")]
|
||||||
|
struct Args {
|
||||||
|
/// Redis URL for job queue
|
||||||
|
#[arg(short, long, default_value = "redis://localhost:6379")]
|
||||||
|
redis_url: String,
|
||||||
|
|
||||||
|
/// Enable verbose logging
|
||||||
|
#[arg(short, long)]
|
||||||
|
verbose: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initialize logging based on verbosity level
|
||||||
|
fn init_logging(verbose: bool) {
|
||||||
|
if verbose {
|
||||||
|
env_logger::Builder::from_default_env()
|
||||||
|
.filter_level(log::LevelFilter::Debug)
|
||||||
|
.init();
|
||||||
|
} else {
|
||||||
|
env_logger::Builder::from_default_env()
|
||||||
|
.filter_level(log::LevelFilter::Info)
|
||||||
|
.init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create and configure the TUI application
|
||||||
|
fn create_app(args: &Args) -> Result<App> {
|
||||||
|
let actor_id = "osis".to_string();
|
||||||
|
|
||||||
|
// Get the crate root directory
|
||||||
|
let crate_root = std::env::var("CARGO_MANIFEST_DIR")
|
||||||
|
.unwrap_or_else(|_| ".".to_string());
|
||||||
|
let crate_root = PathBuf::from(crate_root);
|
||||||
|
|
||||||
|
let actor_path = crate_root.join("target/debug/actor_osis");
|
||||||
|
let example_dir = Some(crate_root.join("examples/scripts"));
|
||||||
|
|
||||||
|
App::new(
|
||||||
|
actor_id,
|
||||||
|
actor_path,
|
||||||
|
args.redis_url.clone(),
|
||||||
|
example_dir,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Spawn the actor binary as a background process
|
||||||
|
fn spawn_actor_process(_args: &Args) -> Result<Child> {
|
||||||
|
// Get the crate root directory
|
||||||
|
let crate_root = std::env::var("CARGO_MANIFEST_DIR")
|
||||||
|
.unwrap_or_else(|_| ".".to_string());
|
||||||
|
let actor_path = PathBuf::from(crate_root).join("target/debug/actor_osis");
|
||||||
|
info!("🎬 Spawning actor process: {}", actor_path.display());
|
||||||
|
|
||||||
|
let mut cmd = Command::new(&actor_path);
|
||||||
|
|
||||||
|
// Redirect stdout and stderr to null to prevent logs from interfering with TUI
|
||||||
|
cmd.stdout(std::process::Stdio::null())
|
||||||
|
.stderr(std::process::Stdio::null());
|
||||||
|
|
||||||
|
// Spawn the process
|
||||||
|
let child = cmd
|
||||||
|
.spawn()
|
||||||
|
.with_context(|| format!("Failed to spawn actor process: {}", actor_path.display()))?;
|
||||||
|
|
||||||
|
info!("✅ Actor process spawned with PID: {}", child.id());
|
||||||
|
Ok(child)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cleanup function to terminate actor process
|
||||||
|
fn cleanup_actor_process(mut actor_process: Child) {
|
||||||
|
info!("🧹 Cleaning up actor process...");
|
||||||
|
|
||||||
|
match actor_process.try_wait() {
|
||||||
|
Ok(Some(status)) => {
|
||||||
|
info!("Actor process already exited with status: {}", status);
|
||||||
|
}
|
||||||
|
Ok(None) => {
|
||||||
|
info!("Terminating actor process...");
|
||||||
|
if let Err(e) = actor_process.kill() {
|
||||||
|
error!("Failed to kill actor process: {}", e);
|
||||||
|
} else {
|
||||||
|
match actor_process.wait() {
|
||||||
|
Ok(status) => info!("Actor process terminated with status: {}", status),
|
||||||
|
Err(e) => error!("Failed to wait for actor process: {}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("Failed to check actor process status: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<()> {
|
||||||
|
let args = Args::parse();
|
||||||
|
|
||||||
|
// Initialize logging
|
||||||
|
init_logging(args.verbose);
|
||||||
|
|
||||||
|
let crate_root = std::env::var("CARGO_MANIFEST_DIR")
|
||||||
|
.unwrap_or_else(|_| ".".to_string());
|
||||||
|
|
||||||
|
info!("🚀 Starting Baobab Actor TUI...");
|
||||||
|
info!("Actor ID: osis");
|
||||||
|
info!("Actor Path: {}/target/debug/actor_osis", crate_root);
|
||||||
|
info!("Redis URL: {}", args.redis_url);
|
||||||
|
info!("Example Directory: {}/examples/scripts", crate_root);
|
||||||
|
|
||||||
|
// Spawn the actor process first
|
||||||
|
let actor_process = spawn_actor_process(&args)?;
|
||||||
|
|
||||||
|
// Give the actor a moment to start up
|
||||||
|
tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
|
||||||
|
|
||||||
|
// Create app and run TUI
|
||||||
|
let app = create_app(&args)?;
|
||||||
|
|
||||||
|
// Set up signal handling for graceful shutdown
|
||||||
|
let result = tokio::select! {
|
||||||
|
tui_result = setup_and_run_tui(app) => {
|
||||||
|
info!("TUI exited");
|
||||||
|
tui_result
|
||||||
|
}
|
||||||
|
_ = signal::ctrl_c() => {
|
||||||
|
info!("Received Ctrl+C, shutting down...");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Clean up the actor process
|
||||||
|
cleanup_actor_process(actor_process);
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
53
examples/scripts/heroledger.rhai
Normal file
53
examples/scripts/heroledger.rhai
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
// heroledger.rhai - Demonstration of HeroLedger models in Rhai
|
||||||
|
|
||||||
|
print("=== HeroLedger Models Demo ===");
|
||||||
|
|
||||||
|
// Create a new user
|
||||||
|
print("\n--- Creating User ---");
|
||||||
|
let new_user = new_user()
|
||||||
|
.name("Alice Johnson")
|
||||||
|
.email("alice@herocode.com")
|
||||||
|
.pubkey("0x1234567890abcdef")
|
||||||
|
.status("Active")
|
||||||
|
.save_user();
|
||||||
|
|
||||||
|
print("Created user: " + new_user.get_name());
|
||||||
|
print("User ID: " + new_user.get_id());
|
||||||
|
print("User email: " + new_user.get_email());
|
||||||
|
print("User pubkey: " + new_user.get_pubkey());
|
||||||
|
|
||||||
|
// Create a new group
|
||||||
|
print("\n--- Creating Group ---");
|
||||||
|
let new_group = new_group()
|
||||||
|
.name("HeroCode Developers")
|
||||||
|
.description("A group for HeroCode development team members")
|
||||||
|
.visibility("Public")
|
||||||
|
.save_group();
|
||||||
|
|
||||||
|
print("Created group: " + new_group.get_name());
|
||||||
|
print("Group ID: " + new_group.get_id());
|
||||||
|
print("Group description: " + new_group.get_description());
|
||||||
|
|
||||||
|
// Create a new account
|
||||||
|
print("\n--- Creating Account ---");
|
||||||
|
let new_account = new_account()
|
||||||
|
.name("Alice's Main Account")
|
||||||
|
.description("Primary account for Alice Johnson")
|
||||||
|
.currency("USD")
|
||||||
|
.save_account();
|
||||||
|
|
||||||
|
print("Created account: " + new_account.get_name());
|
||||||
|
print("Account ID: " + new_account.get_id());
|
||||||
|
print("Account currency: " + new_account.get_currency());
|
||||||
|
|
||||||
|
// Create a new DNS zone
|
||||||
|
print("\n--- Creating DNS Zone ---");
|
||||||
|
let new_dns_zone = new_dns_zone()
|
||||||
|
.name("herocode.com")
|
||||||
|
.description("Main domain for HeroCode")
|
||||||
|
.save_dns_zone();
|
||||||
|
|
||||||
|
print("Created DNS zone: " + new_dns_zone.get_name());
|
||||||
|
print("DNS zone ID: " + new_dns_zone.get_id());
|
||||||
|
|
||||||
|
print("\n=== Demo Complete ===");
|
@@ -1,42 +1,4 @@
|
|||||||
//! # Rhailib Domain-Specific Language (DSL) Engine
|
use heromodels::models::heroledger::rhai::register_heroledger_rhai_modules;
|
||||||
//!
|
|
||||||
//! This module provides a comprehensive Domain-Specific Language implementation for the Rhai
|
|
||||||
//! scripting engine, exposing business domain models and operations through a fluent,
|
|
||||||
//! chainable API.
|
|
||||||
//!
|
|
||||||
//! ## Overview
|
|
||||||
//!
|
|
||||||
//! The DSL is organized into business domain modules, each providing Rhai-compatible
|
|
||||||
//! functions for creating, manipulating, and persisting domain entities. All operations
|
|
||||||
//! include proper authorization checks and type safety.
|
|
||||||
//!
|
|
||||||
//! ## Available Domains
|
|
||||||
//!
|
|
||||||
//! - **Business Operations** (`biz`): Companies, products, sales, shareholders
|
|
||||||
//! - **Financial Models** (`finance`): Accounts, assets, marketplace operations
|
|
||||||
//! - **Content Management** (`library`): Collections, images, PDFs, books, slideshows
|
|
||||||
//! - **Workflow Management** (`flow`): Flows, steps, signature requirements
|
|
||||||
//! - **Community Management** (`circle`): Circles, themes, membership
|
|
||||||
//! - **Contact Management** (`contact`): Contact information and relationships
|
|
||||||
//! - **Access Control** (`access`): Security and permissions
|
|
||||||
//! - **Time Management** (`calendar`): Calendar and scheduling
|
|
||||||
//! - **Core Utilities** (`core`): Comments and fundamental operations
|
|
||||||
//! - **Generic Objects** (`object`): Generic object manipulation
|
|
||||||
//!
|
|
||||||
//! ## Usage Example
|
|
||||||
//!
|
|
||||||
//! ```rust
|
|
||||||
//! use rhai::Engine;
|
|
||||||
//! use crate::engine::register_dsl_modules;
|
|
||||||
//!
|
|
||||||
//! let mut engine = Engine::new();
|
|
||||||
//! register_dsl_modules(&mut engine);
|
|
||||||
//!
|
|
||||||
//! // Now the engine can execute scripts like:
|
|
||||||
//! // let company = new_company().name("Acme Corp").email("contact@acme.com");
|
|
||||||
//! // let saved = save_company(company);
|
|
||||||
//! ```
|
|
||||||
|
|
||||||
use rhai::Engine;
|
use rhai::Engine;
|
||||||
use rhailib_dsl;
|
use rhailib_dsl;
|
||||||
use std::sync::{Arc, OnceLock};
|
use std::sync::{Arc, OnceLock};
|
||||||
@@ -161,6 +123,8 @@ pub fn register_dsl_modules(engine: &mut Engine) {
|
|||||||
|
|
||||||
// Register basic object functionality directly
|
// Register basic object functionality directly
|
||||||
register_object_functions(engine);
|
register_object_functions(engine);
|
||||||
|
heromodels::heroledger::rhai::register_heroledger_rhai_modules(&mut engine);
|
||||||
|
|
||||||
|
|
||||||
println!("Rhailib Domain Specific Language modules registered successfully.");
|
println!("Rhailib Domain Specific Language modules registered successfully.");
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user