Skip to content
Merged
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions crates/aingle/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "aingle"
version = "0.4.2"
version = "0.6.0"
description = "AIngle, a framework for distributed applications"
license = "Apache-2.0 OR LicenseRef-Commercial"
homepage = "https://apilium.com"
Expand All @@ -26,14 +26,14 @@ ghost_actor = "0.3.0-alpha.1"
ai_hash = { version = ">=0.0.1", path = "../ai_hash", features = ["full"] }
aingle_cascade = { version = "0.0.1", path = "../aingle_cascade" }
aingle_conductor_api = { version = "0.0.1", path = "../aingle_conductor_api" }
aingle_ai = { version = "0.4", path = "../aingle_ai", optional = true }
aingle_ai = { version = "0.6", path = "../aingle_ai", optional = true }
aingle_keystore = { version = "0.0.1", path = "../aingle_keystore" }
aingle_p2p = { version = "0.0.1", path = "../aingle_p2p" }
aingle_sqlite = { version = "0.0.1", path = "../aingle_sqlite" }
aingle_middleware_bytes = "=0.0.3"
aingle_state = { version = "0.0.1", path = "../aingle_state" }
aingle_types = { version = "0.0.1", path = "../aingle_types" }
aingle_cortex = { version = "0.4", path = "../aingle_cortex", default-features = false, features = ["rest"] }
aingle_cortex = { version = "0.6", path = "../aingle_cortex", default-features = false, features = ["rest"] }
aingle_wasmer_host = "0.0.1"
aingle_websocket = { version = "0.0.1", path = "../aingle_websocket" }
wasmer = "=7.0.1"
Expand Down
2 changes: 1 addition & 1 deletion crates/aingle_ai/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "aingle_ai"
version = "0.5.0"
version = "0.6.0"
description = "AI integration layer for AIngle - Ineru, Nested Learning, Kaneru"
license = "Apache-2.0 OR LicenseRef-Commercial"
repository = "https://github.com/ApiliumCode/aingle"
Expand Down
2 changes: 1 addition & 1 deletion crates/aingle_contracts/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "aingle_contracts"
version = "0.5.0"
version = "0.6.0"
description = "Smart Contracts DSL and WASM Runtime for AIngle"
license = "Apache-2.0 OR LicenseRef-Commercial"
repository = "https://github.com/ApiliumCode/aingle"
Expand Down
15 changes: 8 additions & 7 deletions crates/aingle_cortex/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "aingle_cortex"
version = "0.5.0"
version = "0.6.0"
description = "Córtex API - REST/GraphQL/SPARQL interface for AIngle semantic graphs"
license = "Apache-2.0 OR LicenseRef-Commercial"
repository = "https://github.com/ApiliumCode/aingle"
Expand All @@ -21,6 +21,7 @@ auth = ["dep:jsonwebtoken", "dep:argon2"]
p2p = ["dep:quinn", "dep:rustls", "dep:rcgen", "dep:ed25519-dalek", "dep:hex"]
p2p-mdns = ["p2p", "dep:mdns-sd", "dep:if-addrs"]
cluster = ["p2p", "dep:aingle_wal", "dep:aingle_raft", "dep:openraft", "dep:tokio-rustls", "dep:rustls-pemfile"]
dag = ["cluster", "aingle_graph/dag", "aingle_graph/dag-sign", "aingle_raft/dag"]
full = ["rest", "graphql", "sparql", "auth"]

[[bin]]
Expand All @@ -29,10 +30,10 @@ path = "src/main.rs"

[dependencies]
# Core AIngle crates
aingle_graph = { version = "0.5", path = "../aingle_graph", features = ["sled-backend"] }
aingle_logic = { version = "0.5", path = "../aingle_logic" }
aingle_zk = { version = "0.5", path = "../aingle_zk" }
ineru = { version = "0.5", path = "../ineru" }
aingle_graph = { version = "0.6", path = "../aingle_graph", features = ["sled-backend"] }
aingle_logic = { version = "0.6", path = "../aingle_logic" }
aingle_zk = { version = "0.6", path = "../aingle_zk" }
ineru = { version = "0.6", path = "../ineru" }

# Web framework
axum = { version = "0.8", features = ["ws", "macros"] }
Expand Down Expand Up @@ -95,8 +96,8 @@ rcgen = { version = "0.13", optional = true }
ed25519-dalek = { version = "2", features = ["rand_core"], optional = true }
hex = { version = "0.4", optional = true }
# Clustering (optional)
aingle_wal = { version = "0.5", path = "../aingle_wal", optional = true }
aingle_raft = { version = "0.5", path = "../aingle_raft", optional = true }
aingle_wal = { version = "0.6", path = "../aingle_wal", optional = true }
aingle_raft = { version = "0.6", path = "../aingle_raft", optional = true }
openraft = { version = "0.10.0-alpha.17", features = ["serde", "type-alias"], optional = true }
tokio-rustls = { version = "0.26", default-features = false, features = ["ring"], optional = true }
rustls-pemfile = { version = "2", optional = true }
Expand Down
116 changes: 115 additions & 1 deletion crates/aingle_cortex/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
cfg
};

// Capture bind address before config is moved (used by cluster bootstrap)
// Capture bind address and db_path before config is moved
#[allow(unused_variables)]
let bind_host = config.host.clone();
#[allow(unused_variables)]
let bind_port = config.port;
#[allow(unused_variables)]
let db_path = config.db_path.clone();

// Create and run server
#[allow(unused_mut)]
Expand Down Expand Up @@ -142,6 +144,118 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
);
}

// Initialize DAG if enabled: enable DAG on the graph, create genesis if needed
#[cfg(feature = "dag")]
{
let state = server.state_mut();

// Enable DAG on the GraphDB (persistent for Sled, in-memory otherwise)
{
let mut graph = state.graph.write().await;
match &db_path {
Some(p) if p != ":memory:" => {
if let Err(e) = graph.enable_dag_persistent(p) {
tracing::error!(
"Failed to enable persistent DAG: {e}. \
Falling back to in-memory DAG — data will NOT survive restarts!"
);
graph.enable_dag();
} else {
tracing::info!("DAG persistence enabled (Sled)");
}
}
_ => {
tracing::warn!("DAG using in-memory backend — data will NOT survive restarts");
graph.enable_dag();
}
}
let triple_count = graph.count();
if let Some(dag_store) = graph.dag_store() {
match dag_store.init_or_migrate(triple_count) {
Ok(genesis_hash) => {
tracing::info!(
hash = %genesis_hash,
triples = triple_count,
"DAG initialized (genesis)"
);
}
Err(e) => {
tracing::error!("DAG initialization failed: {e}");
}
}
}
}

// Set DAG author from cluster node ID
#[cfg(feature = "cluster")]
if let Some(node_id) = state.cluster_node_id {
state.dag_author = Some(aingle_graph::NodeId::named(&format!("node:{}", node_id)));
}

// Initialize Ed25519 signing key for DAG actions.
// Reuses the same node.key seed as P2P identity (deterministic).
{
let key = match &db_path {
Some(p) if p != ":memory:" => {
let key_path = std::path::Path::new(p)
.parent()
.unwrap_or(std::path::Path::new("."))
.join("node.key");
if key_path.exists() {
match std::fs::read(&key_path) {
Ok(seed) if seed.len() == 32 => {
let mut arr = [0u8; 32];
arr.copy_from_slice(&seed);
Some(aingle_graph::dag::DagSigningKey::from_seed(&arr))
}
_ => None,
}
} else {
// Generate new key and persist
let key = aingle_graph::dag::DagSigningKey::generate();
let seed = key.seed();
if let Some(parent) = key_path.parent() {
std::fs::create_dir_all(parent).ok();
}
#[cfg(unix)]
{
use std::io::Write;
use std::os::unix::fs::OpenOptionsExt;
if let Ok(mut f) = std::fs::OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.mode(0o600)
.open(&key_path)
{
let _ = f.write_all(&seed);
}
}
#[cfg(not(unix))]
{
let _ = std::fs::write(&key_path, &seed);
}
Some(key)
}
}
_ => {
// In-memory mode: generate ephemeral key
Some(aingle_graph::dag::DagSigningKey::generate())
}
};

if let Some(ref k) = key {
tracing::info!(
public_key = %k.public_key_hex(),
"DAG signing key loaded (Ed25519)"
);
}
state.dag_signing_key = key.map(std::sync::Arc::new);
}

tracing::info!("Semantic DAG v0.6.0 enabled");
}

// Keep a reference to the state for shutdown flush
let state_for_shutdown = server.state().clone();
let snapshot_dir_for_shutdown = snapshot_dir.clone();
Expand Down
Loading
Loading