# π§ Rust Logic Graph
[](https://www.rust-lang.org/)
[](https://opensource.org/licenses/MIT)
[](https://github.com/KSD-CO/rust-logic-graph)
[](https://github.com/KSD-CO/rust-logic-graph/actions)
A high-performance **reasoning graph framework** for Rust with **GRL (Grule Rule Language)** support. Build complex workflows with conditional execution, topological ordering, and async processing.
---
## β¨ Key Features
- π₯ **GRL Support** - [rust-rule-engine v0.17](https://crates.io/crates/rust-rule-engine)
- π **Topological Execution** - Automatic DAG-based node ordering
- β‘ **Async Runtime** - Built on Tokio for high concurrency
- β‘ **Parallel Execution** - Automatic parallel execution of independent nodes (v0.5.0)
- πΎ **Caching Layer** - High-performance result caching with TTL, eviction policies, and memory limits (v0.5.0)
- π§ **Memory Optimization** - Context pooling and allocation tracking (v0.7.0)
- π οΈ **CLI Developer Tools** - Graph validation, dry-run, profiling, and visualization (v0.5.0)
- π¨ **Web Graph Editor** - Next.js visual editor with drag-and-drop interface (v0.8.0)
- π **YAML Configuration** - Declarative graph definitions with external config files (v0.8.5)
- π― **Advanced Control Flow** - Subgraphs, conditionals, loops, error handling (v0.9.0) π
- π **Multiple Node Types** - RuleNode, DBNode, AINode, ConditionalNode, LoopNode, TryCatchNode, RetryNode, CircuitBreakerNode
- π **JSON/YAML Configuration** - Simple workflow definitions
- π― **98% Drools Compatible** - Easy migration from Java
- π **Streaming Processing** - Stream-based execution with backpressure (v0.3.0)
- ποΈ **Database Integrations** - PostgreSQL, MySQL, Redis, MongoDB (v0.2.0)
- π€ **AI/LLM Integrations** - OpenAI, Claude, Ollama (v0.2.0)
---
## π Quick Start
### Installation
```toml
[dependencies]
rust-logic-graph = "0.9.0"
# With specific integrations
rust-logic-graph = { version = "0.9.0", features = ["postgres", "openai"] }
# With all integrations
rust-logic-graph = { version = "0.9.0", features = ["all-integrations"] }
```
## π’ Real-World Case Study: Purchasing Flow System
See a complete production implementation in **[case_study/](case_study/)** - A full-featured purchasing automation system built with Rust Logic Graph.
### π System Overview
**Problem**: Automate purchasing decisions for inventory replenishment across multiple products, warehouses, and suppliers.
**Solution**: Business rules in GRL decide when/how much to order. Orchestrator executes the workflows.
### π― Two Architecture Implementations
The purchasing flow system demonstrates the same business logic implemented in **two different architectures** - showcasing rust-logic-graph's flexibility for different deployment scenarios.
#### **Architecture Comparison: Pros, Cons & Use Cases**
| Aspect | π’ **Monolithic** | π **Microservices** |
|--------|------------------|---------------------|
| **β
Advantages** | β’ **Fast development** - Single codebase, quick iterations<br>β’ **Low latency** - In-process calls (~10ms)<br>β’ **Simple deployment** - Single binary<br>β’ **Easy debugging** - Single process, simple logs<br>β’ **Low cost** - ~50MB RAM, 1 CPU<br>β’ **YAML flexibility** - Change workflows without rebuild | β’ **Horizontal scaling** - Scale services independently<br>β’ **Team autonomy** - Separate service ownership<br>β’ **Fault isolation** - Service failure β system failure<br>β’ **Tech flexibility** - Different languages per service<br>β’ **Independent deploys** - Update without full restart<br>β’ **Production proven** - Battle-tested at scale |
| **β Disadvantages** | β’ **Vertical scaling only** - Limited by single machine<br>β’ **Single point of failure** - Process crash = full outage<br>β’ **Tight coupling** - All code in one repo<br>β’ **Resource competition** - Services share CPU/RAM<br>β’ **Deployment risk** - One deploy affects everything | β’ **Network overhead** - gRPC calls (~56ms, 5.6x slower)<br>β’ **Complex setup** - Docker, K8s, service mesh<br>β’ **High resource usage** - ~500MB RAM, 7 containers<br>β’ **Debugging complexity** - Distributed tracing needed<br>β’ **Development friction** - Slower build/test cycles<br>β’ **Infrastructure cost** - More servers required |
| **π― Best Use Cases** | β
**Startups** - MVP, validate quickly<br>β
**Small teams** (1-5 devs)<br>β
**Low-medium traffic** (<1K req/min)<br>β
**Cost-sensitive** projects<br>β
**Frequent changes** - Business logic evolves<br>β
**Simple ops** - Limited DevOps resources | β
**High scale** (>10K req/min)<br>β
**Large teams** (15+ devs, multiple teams)<br>β
**Critical uptime** - 99.99% SLA<br>β
**Independent services** - Different release cycles<br>β
**Polyglot needs** - Mix languages/frameworks<br>β
**Regulatory** - Service isolation required |
| **β οΈ Anti-patterns** | β Don't use if:<br>β’ Need >10K requests/min<br>β’ Team >15 developers<br>β’ Services need independent scaling<br>β’ Require 99.99% uptime | β Don't use if:<br>β’ Team <5 developers<br>β’ Traffic <1K requests/min<br>β’ Premature optimization<br>β’ No DevOps expertise |
| **ποΈ Architecture** | Single HTTP service (Port 8080)<br>4 PostgreSQL DBs (multi-database)<br>YAML-driven graph execution | 7 services (gRPC + HTTP)<br>4 PostgreSQL DBs (service-owned)<br>Hardcoded gRPC graph topology |
| **π Performance** | ~10ms latency (in-process)<br>~50MB RAM, 1 CPU core | ~56ms latency (network calls)<br>~500MB RAM, 7 containers |
#### **When to Use Each Architecture**
**β
Use Monolithic When:**
- π **Early stage startup** - Fast iteration, quick deployments
- π° **Limited resources** - Small team, limited infrastructure budget
- π **Low-medium traffic** - <1000 requests/minute
- π― **MVP/Prototype** - Need to validate business logic quickly
- π οΈ **Simple operations** - Single deployment, easy monitoring
- π₯ **Small team** - 1-5 developers, full-stack ownership
- π§ **Frequent changes** - Business logic changes often, need flexibility
- π΅ **Cost-sensitive** - Minimize cloud costs, fewer resources
**Monolithic Example (Port 8080):**
```bash
cd case_study/monolithic
cargo run --release
curl -X POST http://localhost:8080/purchasing/flow \
-H "Content-Type: application/json" \
-d '{"product_id": "PROD-001"}'
```
**β
Use Microservices When:**
- π **High scale** - >10,000 requests/minute, need horizontal scaling
- π₯ **Large team** - Multiple teams, service ownership per team
- π§ **Independent deployments** - Deploy services independently
- π‘οΈ **Fault isolation** - Service failure shouldn't crash entire system
- π **Polyglot needs** - Different services in different languages
- π **Different SLAs** - Critical services need higher availability
- π **Complex monitoring** - Distributed tracing, service mesh
- π° **Budget for infrastructure** - Can afford Kubernetes, service mesh
**Microservices Example (7 Services):**
```bash
cd case_study/microservices
docker compose up -d
curl -X POST http://localhost:8080/api/purchasing/flow \
-H "Content-Type: application/json" \
-d '{"product_id": "PROD-001"}'
```
#### **Migration Path: Start Monolithic β Scale to Microservices**
1. **Phase 1: Start Monolithic**
- Build and validate business logic
- Use YAML config for flexibility
- Deploy single binary
2. **Phase 2: Extract Critical Services**
- Identify bottlenecks (e.g., Rule Engine)
- Extract to separate service
- Keep rest monolithic
3. **Phase 3: Full Microservices**
- Split all services when scale demands
- Add service mesh, observability
- Use Kubernetes for orchestration
**Both implementations use:**
- β
Same GRL business rules (15 rules in `purchasing_rules.grl`)
- β
Same graph topology (OMS β Inventory β Supplier β UOM β RuleEngine β PO)
- β
rust-logic-graph's Graph/Executor pattern
- β
Clean architecture principles
### π₯ GRL Business Rules (15 Rules)
```grl
rule "CalculateShortage" salience 120 no-loop {
when
required_qty > 0
then
Log("Calculating shortage...");
shortage = required_qty - available_qty;
Log("Shortage calculated");
}
rule "OrderMOQWhenShortageIsLess" salience 110 no-loop {
when
shortage > 0 && shortage < moq && is_active == true
then
Log("Shortage less than MOQ, ordering MOQ");
order_qty = moq;
}
```
**See full rules**: [purchasing_rules.grl](case_study/microservices/services/rule-engine-service/rules/purchasing_rules.grl)
### YAML Configuration (NEW in v0.8.5)
Both Monolithic and Microservices implementations support **YAML-based graph configuration**, but with different approaches:
**Monolithic YAML Example** (`purchasing_flow_graph.yaml`):
```yaml
nodes:
oms_history:
type: DBNode
database: "oms_db" # Multi-database routing
query: "SELECT product_id, avg_daily_demand::float8, trend FROM oms_history WHERE product_id = $1"
inventory_levels:
type: DBNode
database: "inventory_db"
query: "SELECT product_id, available_qty::float8, reserved_qty::float8 FROM inventory WHERE product_id = $1"
rule_engine:
type: RuleNode
description: "Evaluate business rules with dynamic field mapping"
dependencies:
- oms_history
- inventory_levels
- supplier_info
- uom_conversion
field_mappings: # Dynamic field extraction (NEW)
avg_daily_demand: "oms_history.avg_daily_demand"
available_qty: "inventory_levels.available_qty"
lead_time: "supplier_info.lead_time"
moq: "supplier_info.moq"
create_po:
type: RuleNode
dependencies:
- rule_engine
field_mappings:
should_order: "rule_engine.should_order"
recommended_qty: "rule_engine.recommended_qty"
product_id: "supplier_info.product_id"
edges:
- from: oms_history
to: rule_engine
- from: inventory_levels
to: rule_engine
- from: rule_engine
to: create_po
```
**Microservices YAML Example** (`purchasing_flow_graph.yaml`):
```yaml
nodes:
oms_grpc:
type: GrpcNode
query: "http://localhost:50051#GetOrderHistory"
description: "Fetch order management data via gRPC"
inventory_grpc:
type: GrpcNode
query: "http://localhost:50052#GetInventoryLevels"
description: "Fetch inventory levels via gRPC"
supplier_grpc:
type: GrpcNode
query: "http://localhost:50053#GetSupplierInfo"
description: "Fetch supplier information via gRPC"
uom_grpc:
type: GrpcNode
query: "http://localhost:50054#ConvertUnits"
description: "Fetch UOM conversions via gRPC"
rule_engine_grpc:
type: RuleNode
description: "Evaluate business rules"
dependencies:
- oms_grpc
- inventory_grpc
- supplier_grpc
- uom_grpc
po_grpc:
type: RuleNode
description: "Create purchase order"
dependencies:
- rule_engine_grpc
edges:
- from: oms_grpc
to: rule_engine_grpc
- from: inventory_grpc
to: rule_engine_grpc
- from: supplier_grpc
to: rule_engine_grpc
- from: uom_grpc
to: rule_engine_grpc
- from: rule_engine_grpc
to: po_grpc
```
**Key Differences:**
| Feature | Monolithic YAML | Microservices YAML |
|---------|----------------|-------------------|
| **Node Type** | `DBNode` (direct SQL) | `GrpcNode` (service calls) |
| **Query** | SQL queries | gRPC endpoint URLs |
| **Database Routing** | `database: "oms_db"` | No database (delegates to services) |
| **Field Mappings** | β
Dynamic via YAML | β Hardcoded in Node implementations |
| **Flexibility** | 100% config-driven | Hybrid (topology in YAML, logic in code) |
**Benefits:**
- β
**70% less code** - Graph definition moves from Rust to YAML
- β
**No recompile** - Change workflows without rebuilding
- β
**Dynamic field mapping** (Monolithic only) - Zero hardcoded field names
- β
**Multi-database routing** (Monolithic only) - Each node specifies its database
- β
**Service URLs** (Microservices only) - Configure gRPC endpoints
- β
**Better readability** - Clear, declarative graph structure
- β
**Easy testing** - Test with different configurations
**Key Architecture Differences:**
| Aspect | Monolithic | Microservices |
|--------|-----------|---------------|
| **Service Count** | 1 service | 7 services (Orchestrator, OMS, Inventory, Supplier, UOM, RuleEngine, PO) |
| **Ports** | Single port 8080 | Orchestrator: 8080, Services: 50051-50056 (gRPC) |
| **Database Access** | Direct SQL queries to 4 DBs | gRPC calls to service APIs |
| **Field Mapping** | YAML `field_mappings` config | Hardcoded in gRPC node implementations |
| **Rule Engine** | In-process RuleEngine call | gRPC to rule-engine-service :50055 |
| **Communication** | Function calls (0 network) | gRPC (network overhead) |
| **Graph Executor** | `PurchasingGraphExecutor` | `OrchestratorExecutor` with gRPC nodes |
| **Node Types** | `DynamicDBNode`, `DynamicRuleNode` | `OmsGrpcNode`, `InventoryGrpcNode`, etc. |
| **Configuration** | 100% YAML-driven | Partially hardcoded gRPC contracts |
| **Flexibility** | Change workflow via YAML only | Need code changes for new services |
| **Dependencies** | rust-logic-graph + sqlx | rust-logic-graph + tonic + prost |
| **Deployment** | `cargo run` or single binary | `docker compose up` (11 containers) |
| **Development** | Hot reload, fast compile | Rebuild multiple containers |
| **Production Ready** | β
Yes (single binary) | β
Yes (Docker/K8s) |
**Example Response Time Comparison:**
```
Monolithic (in-process):
βββββββββββββββββββββββββββββββββββββββ
β HTTP Request β Graph Executor β ~2ms
β ββ DB Query (oms_db) β ~1ms
β ββ DB Query (inventory_db) β ~1ms
β ββ DB Query (supplier_db) β ~1ms
β ββ DB Query (uom_db) β ~1ms
β ββ Rule Engine (in-process) β ~2ms
β ββ Create PO (in-process) β ~2ms
β Total: ~10ms β
βββββββββββββββββββββββββββββββββββββββ
Microservices (network calls):
βββββββββββββββββββββββββββββββββββββββ
β HTTP Request β Orchestrator β ~2ms
β ββ gRPC OMS Service (50051) β ~8ms (network + DB)
β ββ gRPC Inventory (50052) β ~8ms (network + DB)
β ββ gRPC Supplier (50053) β ~8ms (network + DB)
β ββ gRPC UOM (50054) β ~8ms (network + DB)
β ββ gRPC Rule Engine (50055) β ~12ms (network + rules)
β ββ gRPC PO Service (50056) β ~10ms (network + create)
β Total: ~56ms (5.6x slower) β
βββββββββββββββββββββββββββββββββββββββ
```
**Trade-offs Summary:**
| Consideration | Monolithic Wins | Microservices Wins |
|---------------|----------------|-------------------|
| **Performance** | β
5-10x faster | β Network overhead |
| **Simplicity** | β
Single process | β Complex setup |
| **Resource Usage** | β
~50MB RAM | β ~500MB RAM |
| **Development Speed** | β
Faster iteration | β Slower builds |
| **Scalability** | β Vertical only | β
Horizontal scale |
| **Team Autonomy** | β Shared codebase | β
Independent teams |
| **Fault Isolation** | β Single point of failure | β
Service isolation |
| **Deployment** | β
Single binary | β Multi-container |
| **Monitoring** | β
Simple logs | β Distributed tracing |
| **Cost** | β
Lower infra cost | β Higher infra cost |
**Real-World Recommendation:**
```
Traffic Level | Recommended Architecture
-----------------------|-------------------------
< 100 req/min | Monolithic (overkill to use microservices)
100-1,000 req/min | Monolithic (scales easily vertically)
1,000-10,000 req/min | Monolithic or Hybrid (extract bottlenecks)
> 10,000 req/min | Microservices (horizontal scaling needed)
Team Size | Recommended Architecture
-----------------------|-------------------------
1-5 developers | Monolithic (single codebase)
5-15 developers | Monolithic or Hybrid
15-50 developers | Microservices (team per service)
> 50 developers | Microservices (clear boundaries)
```
**Documentation**: See [YAML_CONFIGURATION_SUMMARY.md](case_study/YAML_CONFIGURATION_SUMMARY.md)
### Microservices Communication Flow
After v0.8.0 refactor, the Orchestrator now uses **rust-logic-graph's Graph/Executor pattern** to coordinate microservices:
- The Orchestrator receives a purchasing request (HTTP) and creates a **Graph** with 6 custom **gRPC Nodes**.
- Each Node wraps a gRPC call to a service: `OmsGrpcNode`, `InventoryGrpcNode`, `SupplierGrpcNode`, `UomGrpcNode`, `RuleEngineGrpcNode`, `PoGrpcNode`.
- The **Executor** runs the graph in topological order:
1. **Data Collection Phase** (parallel): OMS, Inventory, Supplier, UOM nodes execute simultaneously via gRPC
2. **Rule Evaluation Phase**: RuleEngineGrpcNode waits for all data, then evaluates GRL rules
3. **Execution Phase**: PoGrpcNode creates/sends PO based on rule decisions
- All business logic (decision flags, calculations) comes from GRL rules. The Orchestrator is a pure executor.
**Graph Topology**:
```
OMS Node βββββ
β
Inventory ββββΌβββ RuleEngine Node βββ PO Node
β
Supplier βββββ€
β
UOM Node βββββ
```
**Benefits of Graph/Executor Pattern**:
- β
**Declarative**: Define workflow as nodes + edges instead of imperative code
- β
**Parallel Execution**: Data nodes run concurrently automatically
- β
**Type Safety**: Custom Node implementations with Rust's type system
- β
**Testable**: Each node can be tested in isolation
- β
**Consistent**: Same pattern used in monolithic and microservices
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CLIENT (HTTP REST) β
ββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β POST /api/purchasing/flow
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Orchestrator Service (Port 8080) - main.rs β
β β
β HTTP Endpoint β OrchestratorGraphExecutor β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β rust-logic-graph Graph Executor β β
β β (graph_executor.rs) β β
β β β β
β β Creates Graph with 6 Custom gRPC Nodes: β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β OmsGrpcNode β β β
β β β β’ impl Node trait from rust-logic-graph β β β
β β β β’ async fn run() β gRPC call to :50051 β β β
β β β β’ Returns JSON to Context β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β InventoryGrpcNode β gRPC :50052 β β β
β β β SupplierGrpcNode β gRPC :50053 β β β
β β β UomGrpcNode β gRPC :50054 β β β
β β β RuleEngineGrpcNode β gRPC :50056 β β β
β β β PoGrpcNode β gRPC :50055 β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β
β β Graph Topology (hardcoded in graph_executor.rs): β β
β β OMS ββββββββ β β
β β Inventory ββΌββ RuleEngine βββ PO β β
β β Supplier βββ€ β β
β β UOM ββββββββ β β
β β β β
β β Executor runs in topological order β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββΌβββββββββββββββββββ¬βββββββββββββββββ¬βββββββββββββββ
β (Parallel) β (Parallel) β (Parallel) β (Parallel) β
βΌ βΌ βΌ βΌ β
ββββββββββββ ββββββββββββββ βββββββββββββββ βββββββββββββ β
βOMS :50051β βInventory β βSupplier β βUOM :50054 β β
β (gRPC) β β:50052 β β:50053 β β (gRPC) β β
β β β (gRPC) β β (gRPC) β β β β
ββ’ History β ββ’ Levels β ββ’ Pricing β ββ’ Convert β β
ββ’ Demand β ββ’ Available β ββ’ Lead Time β ββ’ Factors β β
β β β β ββ’ MOQ β β β β
ββββββ¬ββββββ βββββββ¬βββββββ ββββββββ¬βββββββ βββββββ¬ββββββ β
β β β β β
ββββββββββββββββ΄βββββββββββββββββ΄ββββββββββββββββ β
β β
β Data stored in Graph Context β
βΌ β
βββββββββββββββββββ β
β Rule Engine β (Port 50056 - gRPC) β
β :50056 β β
β (gRPC) β β
β β β
β β’ Loads GRL β β’ Evaluates 15 rules β
β rules from β β’ Returns decision flags β
β .grl file β β’ NO side effects β
β β’ Pure function β β’ Calculations + flags β
ββββββββββ¬βββββββββ β
β β
β Flags stored in Graph Context β
βΌ β
βββββββββββββββββββ β
β PO Service β (Port 50055 - gRPC) β
β :50055 ββββββββββββββββββββββββββββββββ
β (gRPC) β
β β
β β’ Create PO β β’ Reads flags from context
β β’ Send to β β’ Executes based on rules
β Supplier β β’ Email/API delivery
βββββββββββββββββββ
```
**Note**: The Orchestrator uses **rust-logic-graph's Graph/Executor pattern** - each gRPC service call is wrapped in a custom `Node` implementation. The Rule Engine returns decision flags to the Graph Context, and the PoGrpcNode reads these flags to determine whether to create/send the PO.
### Where rust-logic-graph is Used
**Monolithic App** (`case_study/monolithic/`):
- Uses `Graph`, `Executor`, and custom `Node` implementations
- **Multi-database architecture**: 4 separate PostgreSQL databases (oms_db, inventory_db, supplier_db, uom_db)
- **Dynamic field mapping**: YAML-configured field extraction with zero hardcoded field names
- **Config-driven nodes**: `DynamicDBNode` and `DynamicRuleNode` read behavior from YAML
- Database routing via `database` field in YAML (e.g., `database: "oms_db"`)
- Field mappings via `field_mappings` in YAML (e.g., `avg_daily_demand: "oms_history.avg_daily_demand"`)
- `RuleEngineService` accepts `HashMap<String, Value>` for complete flexibility
- Graph structure defined in `purchasing_flow_graph.yaml`
- Single process, no network calls
**Orchestrator Microservice** (`case_study/microservices/services/orchestrator-service/`):
- Uses `Graph`, `Executor`, and custom gRPC `Node` implementations
- 6 gRPC nodes make network calls to remote services
- Same graph topology as monolithic
- Distributed across multiple processes
**Rule Engine Service** (`case_study/microservices/services/rule-engine-service/`):
- Uses `RuleEngine` for GRL evaluation
- Exposed via gRPC endpoint
- Stateless service (no graph execution)
**Other Microservices** (OMS, Inventory, Supplier, UOM, PO):
- Standard gRPC services with database access
- Do NOT use rust-logic-graph directly
- Called by Orchestrator's Graph Executor
**Architecture Highlights:**
**Monolithic Clean Architecture:**
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β HTTP REST API (Port 8080) β
β POST /purchasing/flow {product_id} β
ββββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β PurchasingGraphExecutor (executors/graph_executor.rs) β
β (Clean Architecture) β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β rust-logic-graph Graph/Executor Engine β β
β β β β
β β execute_with_config(product_id, "purchasing_flow.yaml") β β
β β β β
β β 1. GraphConfig::from_yaml_file("purchasing_flow.yaml") β β
β β 2. Parse nodes + edges + field_mappings β β
β β 3. For each node in YAML: β β
β β β’ Create DynamicDBNode (with database routing) β β
β β β’ Create DynamicRuleNode (with field_mappings) β β
β β 4. Register all nodes to Executor β β
β β 5. Execute graph in topological order β β
β β β β
β β Graph Topology (from YAML): β β
β β oms_history βββββββββ β β
β β inventory_levels ββββΌβββ rule_engine βββ create_po β β
β β supplier_info βββββββ€ β β
β β uom_conversion ββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββΌβββββββββββββββββββ¬βββββββββββββββββββ¬ββββββββββββ
β (Parallel DBs) β (Parallel DBs) β (Parallel DBs) β (Parallel)β
βΌ βΌ βΌ βΌ β
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β oms_db β β inventory_db β β supplier_db β β uom_db β β
β PostgreSQL β β PostgreSQL β β PostgreSQL β β PostgreSQL β β
β :5433 β β :5434 β β :5435 β β :5436 β β
β β β β β β β β β
β β’ history β β β’ levels β β β’ info β β β’ conversion β β
β β’ demand β β β’ available β β β’ pricing β β β’ factors β β
β β’ trends β β β’ reserved β β β’ lead_time β β β β
ββββββββ¬ββββββββ ββββββββ¬ββββββββ ββββββββ¬ββββββββ ββββββββ¬ββββββββ β
β β β β β
β DynamicDBNode β DynamicDBNode β DynamicDBNode β Dynamic β
β database:"oms" β database:"inv" β database:"sup" β DB Node β
βββββββββββββββββββ΄ββββββββββββββββββ΄ββββββββββββββββββ΄ββββββββββββ
β
Data stored in Graph Context
with path notation (e.g., "oms_history.avg_daily_demand")
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββ
β DynamicRuleNode (rule_engine) β
β β
β YAML field_mappings config: β
β ββββββββββββββββββββββββββββββββββββββ β
β β avg_daily_demand: β β
β β "oms_history.avg_daily_demand" β β
β β available_qty: β β
β β "inventory_levels.available_qty" β β
β β lead_time: β β
β β "supplier_info.lead_time" β β
β β ... (9 total mappings) β β
β ββββββββββββββββββββββββββββββββββββββ β
β β
β extract_rule_inputs() loop: β
β β’ Reads field_mappings from YAML β
β β’ Uses get_value_by_path() for parsing β
β β’ Returns HashMap<String, Value> β
β β’ ZERO hardcoded field names! β
ββββββββββββββββ¬ββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββ
β RuleEngineService (In-Process) β
β β
β evaluate(HashMap<String, Value>) β
β β
β β’ Loads purchasing_rules.grl β
β β’ 15 business rules (GRL) β
β β’ Accepts dynamic HashMap input β
β β’ No struct, no hardcoded fields β
β β’ Pure functional evaluation β
β β
β Rules calculate: β
β β shortage = required_qty - available β
β β order_qty (respects MOQ) β
β β total_amount with discounts β
β β requires_approval flag β
β β should_create_po flag β
ββββββββββββββββ¬ββββββββββββββββββββββββββββ
β
Decision flags returned to Context
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββ
β DynamicRuleNode (create_po) β
β β
β YAML field_mappings config: β
β ββββββββββββββββββββββββββββββββββββββ β
β β should_order: β β
β β "rule_engine.should_order" β β
β β recommended_qty: β β
β β "rule_engine.recommended_qty" β β
β β product_id: β β
β β "supplier_info.product_id" β β
β β ... (6 total mappings) β β
β ββββββββββββββββββββββββββββββββββββββ β
β β
β β’ Reads rule_engine output from context β
β β’ Dynamic field extraction via YAML β
β β’ Creates PO if should_order == true β
β β’ Returns PO JSON or null β
ββββββββββββββββββββββββββββββββββββββββββββ
```
**Key Design Principles:**
1. **Multi-Database Routing** - Each node specifies its database in YAML:
```yaml
oms_history:
database: "oms_db" # Routes to oms_db pool
```
2. **Dynamic Field Mapping** - Zero hardcoded fields in Rust code:
```yaml
field_mappings:
avg_daily_demand: "oms_history.avg_daily_demand"
```
```rust
// Code is 100% generic
for (key, path) in &self.field_mappings {
inputs.insert(key.clone(), get_value_by_path(ctx, path));
}
```
3. **Config-Driven Execution** - Graph structure in YAML, not Rust:
```rust
executor.execute_with_config("PROD-001", "purchasing_flow_graph.yaml")?;
```
4. **HashMap-Based RuleEngine** - Accepts any fields:
```rust
pub fn evaluate(&mut self, inputs: HashMap<String, Value>) -> Result<Output>
```
**Microservices Communication Flow**
1. **Multi-Database Routing** (`graph_executor.rs`):
```rust
// YAML config specifies database per node
oms_history:
database: "oms_db"
query: "SELECT ..."
// Executor routes to correct pool
let pool = self.get_pool(node_config.database.as_deref());
```
2. **Dynamic Field Mapping** (`graph_executor.rs`):
```rust
// YAML config defines field mappings
field_mappings:
avg_daily_demand: "oms_history.avg_daily_demand"
available_qty: "inventory_levels.available_qty"
// Code extracts dynamically (zero hardcoding)
fn extract_inputs(&self, ctx: &Context) -> HashMap<String, Value> {
for (key, path) in &self.field_mappings {
if let Some(value) = self.get_value_by_path(ctx, path) {
inputs.insert(key.clone(), value);
}
}
}
```
3. **Config-Driven RuleEngine** (`rule_service.rs`):
```rust
// Accepts HashMap instead of struct - 100% flexible
pub fn evaluate(&mut self, inputs: HashMap<String, Value>) -> Result<Output> {
// Uses any fields present in HashMap
// No hardcoded field requirements
}
```
### Web Graph Editor (NEW in v0.8.0)
**π Online Editor**: [https://logic-graph-editor.amalthea.cloud/](https://logic-graph-editor.amalthea.cloud/)
Try the visual graph editor online - no installation required! Create workflows, define rules, and visualize your logic graphs with drag-and-drop.
### CLI Tools (v0.5.0)
```bash
# Build the CLI tool
cargo build --release --bin rlg
# Validate a graph
./target/release/rlg validate --file examples/sample_graph.json
# Visualize graph structure
./target/release/rlg visualize --file examples/sample_graph.json --details
# Profile performance
./target/release/rlg profile --file examples/sample_graph.json --iterations 100
# Dry-run without execution
./target/release/rlg dry-run --file examples/sample_graph.json --verbose
```
**[Full CLI Documentation β](docs/CLI_TOOL.md)**
### Run Examples
```bash
# Basic workflow
cargo run --example simple_flow
# GRL rules
cargo run --example grl_rules
# Advanced integration
cargo run --example grl_graph_flow
```
### Advanced Control Flow Usage (v0.9.0) π
#### Conditional Branching
Route execution based on conditions:
```rust
use rust_logic_graph::{Graph, NodeConfig, Edge, Context};
let mut graph = Graph::new();
// Add nodes
graph.add_node("check_inventory", NodeConfig::default());
graph.add_node("process_order", NodeConfig::default());
graph.add_node("notify_supplier", NodeConfig::default());
// Add conditional routing
graph.add_node("route_decision", NodeConfig {
node_type: NodeType::Conditional {
condition: "available_qty > 100".to_string(),
true_branch: "process_order".to_string(),
false_branch: "notify_supplier".to_string(),
},
..Default::default()
});
graph.add_edge(Edge::new("check_inventory", "route_decision"));
graph.add_edge(Edge::new("route_decision", "process_order"));
graph.add_edge(Edge::new("route_decision", "notify_supplier"));
// Execute
let result = graph.execute().await?;
```
#### Loops
Iterate over collections or use while loops:
```rust
// Foreach loop over products
graph.add_node("process_products", NodeConfig {
node_type: NodeType::Loop {
loop_type: LoopType::Foreach {
items_key: "products".to_string(),
item_var: "current_product".to_string(),
body_node: "process_single_product".to_string(),
},
max_iterations: Some(100),
},
..Default::default()
});
// While loop with condition
graph.add_node("retry_until_success", NodeConfig {
node_type: NodeType::Loop {
loop_type: LoopType::While {
condition: "status != 'success'".to_string(),
body_node: "attempt_operation".to_string(),
},
max_iterations: Some(10),
},
..Default::default()
});
```
#### Error Handling
Try/catch patterns for resilient workflows:
```rust
graph.add_node("safe_operation", NodeConfig {
node_type: NodeType::TryCatch {
try_node: "risky_operation".to_string(),
catch_node: Some("handle_error".to_string()),
finally_node: Some("cleanup".to_string()),
},
..Default::default()
});
```
#### Retry Logic
Exponential backoff for transient failures:
```rust
graph.add_node("api_call", NodeConfig {
node_type: NodeType::Retry {
target_node: "external_api".to_string(),
max_attempts: 3,
backoff_ms: 100,
exponential: true,
},
..Default::default()
});
```
#### Circuit Breaker
Fault tolerance for unstable services:
```rust
graph.add_node("protected_service", NodeConfig {
node_type: NodeType::CircuitBreaker {
target_node: "unstable_service".to_string(),
failure_threshold: 5,
timeout_ms: 60000,
},
..Default::default()
});
```
#### Subgraphs
Nested graph execution with input/output mapping:
```rust
graph.add_node("payment_flow", NodeConfig {
node_type: NodeType::Subgraph {
graph_def: payment_graph_def,
input_mapping: vec![("order_id", "id"), ("amount", "total")],
output_key: "payment_result".to_string(),
},
..Default::default()
});
```
**See [examples/](examples/) for complete working examples.**
---
---
## π Documentation
| Document | Description |
|----------|-------------|
| **[π’ Case Study: Purchasing Flow](case_study/docs/README.md)** | Real production system with microservices & monolithic implementations |
| **[π YAML Configuration Guide](case_study/YAML_CONFIGURATION_SUMMARY.md)** | Declarative graph configuration with YAML (NEW in v0.8.5) |
| **[Graph Editor Guide](graph-editor/README.md)** | Visual web-based graph editor with Next.js (NEW in v0.8.0) |
| **[Memory Optimization Guide](docs/MEMORY_OPTIMIZATION.md)** | Context pooling and allocation tracking (v0.7.0) |
| **[CLI Tool Guide](docs/CLI_TOOL.md)** | Developer tools for validation, profiling, and visualization (v0.5.0) |
| **[Cache Guide](docs/CACHE_IMPLEMENTATION.md)** | Caching layer with TTL and eviction policies (v0.5.0) |
| **[Migration Guide](docs/MIGRATION_GUIDE.md)** | Upgrade guide to v0.14.0 with RETE-UL (v0.5.0) |
| **[Integrations Guide](docs/INTEGRATIONS.md)** | Database & AI integrations (v0.2.0) |
| **[GRL Guide](docs/GRL.md)** | Complete GRL syntax and examples |
| **[Use Cases](docs/USE_CASES.md)** | 33+ real-world applications |
| **[Extending](docs/EXTENDING.md)** | Create custom nodes and integrations |
| **[Implementation](docs/IMPLEMENTATION_SUMMARY.md)** | Technical details |
---
## π― Use Cases
Rust Logic Graph powers applications in:
- π° **Finance** - Loan approval, fraud detection, risk assessment
- π **E-commerce** - Dynamic pricing, recommendations, fulfillment
- π₯ **Healthcare** - Patient triage, clinical decisions, monitoring
- π **Manufacturing** - Predictive maintenance, QC automation
- π‘οΈ **Insurance** - Claims processing, underwriting
- π **Marketing** - Lead scoring, campaign optimization
- βοΈ **Compliance** - AML monitoring, GDPR automation
**[View all 33+ use cases β](docs/USE_CASES.md)**
---
## ποΈ Architecture

---
## π₯ GRL Example
```grl
rule "HighValueLoan" salience 100 {
when
loan_amount > 100000 &&
credit_score < 750
then
requires_manual_review = true;
approval_tier = "senior";
}
rule "AutoApproval" salience 50 {
when
credit_score >= 700 &&
income >= loan_amount * 3 &&
debt_ratio < 0.4
then
auto_approve = true;
interest_rate = 3.5;
}
```
**[Learn more about GRL β](docs/GRL.md)**
---
## π Performance
- **RETE-UL Algorithm**: Advanced pattern matching with unlinking (v0.14.0)
- **2-24x Faster**: Than v0.10 at 50+ rules
- **98% Drools Compatible**: Easy migration path
- **Async by Default**: High concurrency support
- **Parallel Execution**: Automatic layer-based parallelism
- **Smart Caching**: Result caching with TTL and eviction policies
---
## π§ͺ Testing & CLI Tools
```bash
# Run all tests
cargo test
# Build CLI tool
cargo build --release --bin rlg
# Validate graph
./target/release/rlg validate --file examples/sample_graph.json
# Visualize graph structure
./target/release/rlg visualize --file examples/sample_graph.json
# Profile performance
./target/release/rlg profile --file examples/sample_graph.json --iterations 100
# Dry-run execution
./target/release/rlg dry-run --file examples/sample_graph.json --verbose
```
**Test Results**: β
32/32 tests passing
**[Learn more about CLI tools β](docs/CLI_TOOL.md)**
---
## π¦ Project Status
**Version**: 0.8.8 (Latest)
**Status**: Production-ready with YAML configuration, web graph editor, and real-world case study
### What's Working
- β
Core graph execution engine
- β
**RETE-UL algorithm** (v0.14.0) - 2-24x faster
- β
Three node types (Rule, DB, AI)
- β
Topological sorting
- β
Async execution
- β
JSON I/O
- β
**Database integrations** (PostgreSQL, MySQL, Redis, MongoDB)
- β
**AI integrations** (OpenAI, Claude, Ollama)
- β
**Streaming processing** with backpressure and chunking
- β
**Parallel execution** with automatic layer detection
- β
**Caching layer** with TTL, eviction policies, memory limits (v0.5.0)
- β
**Memory optimization** with context pooling (v0.7.0)
- β
**CLI Developer Tools** - validate, profile, visualize, dry-run (v0.5.0)
- β
**Web Graph Editor** - Next.js visual editor with drag-and-drop (v0.8.0)
- β
**Production Case Study** - Purchasing flow with microservices & monolithic (v0.8.0)
- β
**YAML Configuration** - Declarative graph definitions (v0.8.5)
- β
Stream operators (map, filter, fold)
- β
Comprehensive documentation
### Roadmap
- [x] Streaming processing (v0.3.0) - COMPLETED β
- [x] Parallel node execution (v0.4.0) - COMPLETED β
- [x] Caching layer (v0.5.0) - COMPLETED β
- [x] CLI Developer Tools (v0.5.0) - COMPLETED β
- [x] RETE-UL upgrade (v0.5.0) - COMPLETED β
- [x] Memory Optimization (v0.7.0) - COMPLETED β
- [x] Web Graph Editor (v0.8.0) - COMPLETED β
- [x] Production Case Study (v0.8.0) - COMPLETED β
- [x] YAML Configuration (v0.8.5) - COMPLETED β
- [ ] GraphQL API (v0.9.0)
- [ ] Production release (v1.0.0)
**See [ROADMAP.md](ROADMAP.md) for details**
---
## π€ Contributing
Contributions welcome! Please:
1. Fork the repository
2. Create your feature branch
3. Write tests for new features
4. Submit a pull request
---
## π Examples
### Core Examples
| Example | Description | Lines |
|---------|-------------|-------|
| `simple_flow.rs` | Basic 3-node pipeline | 36 |
| `advanced_flow.rs` | Complex 6-node workflow | 120 |
| `grl_rules.rs` | GRL rule examples | 110 |
| `grl_graph_flow.rs` | GRL + Graph integration | 140 |
| `postgres_flow.rs` | PostgreSQL integration | 100 |
| `openai_flow.rs` | OpenAI GPT integration | 150 |
| `streaming_flow.rs` | Streaming with backpressure | 200 |
| `parallel_execution.rs` | Parallel node execution | 250 |
### Advanced Control Flow Examples (v0.9.0) π
| Example | Description | Features Demonstrated |
|---------|-------------|----------------------|
| `conditional_flow.rs` | If/else routing based on conditions | ConditionalNode, branch selection |
| `loop_flow.rs` | Foreach and while loop patterns | LoopNode, iteration over arrays |
| `retry_flow.rs` | Exponential backoff retry logic | RetryNode, configurable attempts |
| `error_handling_flow.rs` | Try/catch/finally patterns | TryCatchNode, error recovery |
| `circuit_breaker_flow.rs` | Circuit breaker fault tolerance | CircuitBreakerNode, failure thresholds |
| `subgraph_flow.rs` | Nested graph execution | SubgraphNode, input/output mapping |
**Run examples:**
```bash
# Conditional routing
cargo run --example conditional_flow
# Loop over products
cargo run --example loop_flow
# Retry with backoff
cargo run --example retry_flow
# Error handling
cargo run --example error_handling_flow
# Circuit breaker
cargo run --example circuit_breaker_flow
# Nested subgraphs
cargo run --example subgraph_flow
```
### CLI Tool Examples (v0.5.0)
| File | Description |
|------|-------------|
| `examples/sample_graph.json` | Linear workflow with 5 nodes |
| `examples/cyclic_graph.json` | Graph with cycle for testing |
| `examples/sample_context.json` | Sample input data |
**See [CLI_TOOL.md](docs/CLI_TOOL.md) for usage examples**
---
## π Why Rust Logic Graph?
### vs. Traditional Rule Engines
- β
**Async by default** - No blocking I/O
- β
**Type safety** - Rust's type system
- β
**Modern syntax** - GRL support
- β
**Graph-based** - Complex workflows
### vs. Workflow Engines
- β
**Embedded** - No external services
- β
**Fast** - Compiled Rust code
- β
**Flexible** - Custom nodes
- β
**Rule-based** - Business logic in rules
---
## π Changelog
### v0.8.9 (2025-11-22) - DBNode Parameters Feature
**New Features:**
- π§ **DBNode Context Parameters** - Dynamic query parameter extraction
- Extract SQL parameters from execution context
- `NodeConfig::db_node_with_params()` for parameterized queries
- Support for `$1`, `$2` (PostgreSQL) and `?` (MySQL) placeholders
- Automatic type conversion (String, Number, Boolean, Null)
- Graceful handling of missing parameters
- See [DB Parameters Guide](docs/DB_PARAMS.md)
**API Additions:**
```rust
// Create DBNode with context parameter extraction
NodeConfig::db_node_with_params(
"SELECT * FROM users WHERE id = $1",
vec!["user_id".to_string()]
)
// Set parameters in context
graph.context.set("user_id", json!("USER-123"));
```
**Configuration Support:**
```yaml
nodes:
fetch_user:
node_type: DBNode
query: "SELECT * FROM users WHERE user_id = $1"
params:
- user_id # Extract from context
```
**Testing:**
- 7 new integration tests in `tests/db_params_tests.rs`
- Single/multiple parameter extraction
- Missing parameter handling
- Type conversion tests
- JSON/YAML serialization tests
**Documentation:**
- Complete guide in `docs/DB_PARAMS.md`
- Example: `examples/db_params_flow.rs`
- JSON example: `examples/db_params_graph.json`
**Compatibility:**
- Fully backward compatible
- Existing DBNodes work without changes
- Optional feature (params default to None)
### v0.8.5 (2025-11-20) - YAML Configuration Release
**New Features:**
- π **YAML Configuration Support** - Declarative graph definitions
- Load graph structure from YAML files instead of hardcoded
- `GraphConfig` module for parsing YAML configurations
- Support for both JSON and YAML formats
- 70% code reduction in graph executors
- See [YAML Configuration Guide](case_study/YAML_CONFIGURATION_SUMMARY.md)
- π§ **Enhanced Graph Executor API**
- `execute()` - Use default configuration
- `execute_with_config(config_path)` - Load custom YAML config
- Dynamic node registration from config
- π **Multiple Workflow Support**
- Standard flow (full process)
- Simplified flow (skip optional steps)
- Urgent flow (fast-track)
- Easy to create custom workflows
- ποΈ **Monolithic Clean Architecture** (NEW)
- Multi-database architecture with 4 PostgreSQL databases
- Dynamic field mapping via YAML configuration
- Zero hardcoded field names in code
- Database routing per node via config
- `field_mappings` for flexible data extraction
- `RuleEngineService` accepts `HashMap<String, Value>`
- Config-driven `DynamicDBNode` and `DynamicRuleNode`
- π **Comprehensive Documentation**
- YAML configuration guide with examples
- Before/After comparison showing improvements
- Multiple workflow examples
- Integration guides for both architectures
- Clean architecture patterns documentation
**Improvements:**
- Monolithic and Microservices both support YAML configs
- Reduced boilerplate code by 70% in executors
- Better separation of concerns (config vs. code)
- Easier testing with multiple configurations
- No recompilation needed for workflow changes
- Complete flexibility in field naming and mapping
**Examples:**
```yaml
# Monolithic with multi-database
nodes:
oms_history:
database: "oms_db"
query: "SELECT ..."
rule_engine:
field_mappings:
avg_daily_demand: "oms_history.avg_daily_demand"
```
```rust
// Dynamic field extraction (no hardcoding)
let inputs = self.extract_rule_inputs(ctx);
rule_service.evaluate(inputs)?; // HashMap<String, Value>
```
**Compatibility:**
- All tests passing
- API backward compatible
- Existing hardcoded graphs still work
### v0.8.0 (2025-11-20) - Web Editor & Production Case Study Release
**New Features:**
- π¨ **Web Graph Editor** - Next.js visual editor with drag-and-drop
- Online version: https://logic-graph-editor.amalthea.cloud/
- React Flow-based graph visualization
- Real-time node editing and validation
- Export/import JSON workflows
- See [Graph Editor Guide](graph-editor/README.md)
- π’ **Production Case Study** - Complete purchasing flow system
- Microservices architecture (7 services with gRPC)
- Monolithic architecture (single HTTP service)
- 15 GRL business rules for purchasing decisions
- Kubernetes deployment manifests
- Docker Compose for local development
- Shared GRL rules proving portability
- See [Case Study Documentation](case_study/docs/README.md)
**Improvements:**
- Updated README with case study section
- Added online graph editor link
- Comprehensive production examples
**Compatibility:**
- All tests passing
- API backward compatible
### v0.5.0 (2025-11-06) - Performance & Developer Tools Release
**Breaking Changes:**
- β‘ **Upgraded rust-rule-engine** from v0.10 β v0.14.0
- Now uses RETE-UL algorithm (2-24x faster)
- Better memory efficiency
- Improved conflict resolution
- See [Migration Guide](docs/MIGRATION_GUIDE.md)
**New Features:**
- π οΈ **CLI Developer Tools** (`rlg` binary)
- Graph validation with comprehensive checks
- Dry-run execution mode
- Performance profiling with statistics
- ASCII graph visualization
- See [CLI Tool Guide](docs/CLI_TOOL.md)
- πΎ **Caching Layer** - High-performance result caching
- TTL-based expiration
- Multiple eviction policies (LRU, LFU, FIFO)
- Memory limits and statistics
- See [Cache Guide](docs/CACHE_IMPLEMENTATION.md)
- β‘ **Parallel Node Execution** - Automatic detection and parallel execution
- Layer detection algorithm using topological sort
- Concurrent execution within layers
- Parallelism analysis and statistics
- π **ParallelExecutor** - New executor with parallel capabilities
- π **New Examples** - CLI examples and test graphs
- β
**32 Tests** - Comprehensive test coverage
**Improvements:**
- Updated documentation with CLI tools, caching, and migration guides
- Performance benchmarking utilities
- Example graph files for testing
**Compatibility:**
- All 32 tests passing
- API is backward compatible (100%)
- Performance: 2-24x faster rule matching
### v0.3.0 (2025-11-03) - Streaming & Performance Release
**New Features:**
- π **Streaming Processing** - Stream-based node execution
- Backpressure handling with bounded channels
- Large dataset support with chunking
- Stream operators (map, filter, fold, async map)
- π **New Example** - `streaming_flow.rs` with 6 demonstrations
- β
**8 New Tests** - Streaming module testing
**Performance:**
- Processed 10,000 items in chunks
- ~432 items/sec throughput with backpressure
### v0.2.0 (2025-11-02) - Integrations Release
**New Features:**
- ποΈ **Database Integrations** - PostgreSQL, MySQL, Redis, MongoDB
- π€ **AI/LLM Integrations** - OpenAI GPT-4, Claude 3.5, Ollama
- π **Integration Examples** - `postgres_flow.rs`, `openai_flow.rs`
- π **INTEGRATIONS.md** - Comprehensive integration guide
- ποΈ **Feature Flags** - Optional dependencies for integrations
### v0.1.0 (2025-11-01) - Initial Release
**Core Features:**
- π§ Core graph execution engine
- π₯ GRL (Grule Rule Language) integration
- π Topological sorting
- β‘ Async execution with Tokio
- π Three node types (Rule, DB, AI)
- π JSON I/O for graphs
- π 4 working examples
- β
6/6 tests passing
---
## π License
MIT License - see [LICENSE](LICENSE) for details.
---
## π Links
- **Repository**: https://github.com/KSD-CO/rust-logic-graph
- **rust-rule-engine**: https://crates.io/crates/rust-rule-engine
- **Documentation**: [docs/](docs/)
- **Issues**: [GitHub Issues](https://github.com/KSD-CO/rust-logic-graph/issues)
---
## π₯ Authors
**James Vu** - Initial work
---
## π Acknowledgments
Built with:
- [rust-rule-engine v0.14.0](https://crates.io/crates/rust-rule-engine) - GRL support with RETE-UL
- [Tokio](https://tokio.rs/) - Async runtime
- [Petgraph](https://github.com/petgraph/petgraph) - Graph algorithms
- [Serde](https://serde.rs/) - Serialization
- [Clap](https://github.com/clap-rs/clap) - CLI framework
---
<div align="center">
**β Star us on GitHub if you find this useful! β**
[Documentation](docs/) β’ [Examples](examples/) β’ [Use Cases](docs/USE_CASES.md) β’ [YAML Config Guide](case_study/YAML_CONFIGURATION_SUMMARY.md)
</div>