senclaw/rule-engine
app Luồng xử lý dữ liệu dạng đồ thị: kéo-thả node, nối cổng vào/ra, chạy realtime. Nguồn (webhook, lịch cron, kích hoạt tay) bơm sự kiện vào chuỗi node lọc — rẽ nhánh — biến đổi — gọi HTTP/AI/thông báo. Mỗi node khai báo nhiều cổng ra (true/false, success/failed, N nhánh switch) và nhiều cổng vào có thể gộp (join/merge). Có debug trace từng bước.
Install
senclaw app install senclaw/rule-engine
Verifies sha512 and SenClaw’s signature before writing to disk.
Documentation
Rule Engine — SenClaw Space App
Luồng xử lý dữ liệu dạng đồ thị: node nguồn bơm sự kiện, các node lọc / rẽ nhánh / biến đổi nối với nhau qua cổng có tên, mỗi cạnh mang một bản sao dữ liệu.
Port 4550. MCP server rule-engine-mcp tại /api/mcp/sse.
Đây là bản viết lại bằng Rust của dipper-hub/services/engine-runner (Go) và thư viện lõi dipper-engine. Thiết kế và lý do khác bản gốc: [docs/rule-engine-app-design.md](../../docs/rule-engine-app-design.md).
Khác biệt cốt lõi so với bản Go
| dipper-engine (Go) | app này | |
|---|---|---|
| Định tuyến | rule tự đọc id node kế tiếp từ option rồi ghi vào Next []string | rule phát ra tên cổng; engine tra bảng edges |
| Cổng ra | quy ước đặt tên field (next_success, next_true, map_switch), mỗi rule một kiểu; maping.go chỉ hiểu 3 trường hợp | RuleSpec khai báo cổng, có cả cổng động (switch) |
| Cổng vào | không có — 2 cạnh vào 1 node = node chạy 2 lần | join / merge với barrier, có TTL |
| Cổng lỗi | rule quên set Next → nhánh chết im lặng | cổng error ngầm định cho mọi node; không nối thì vẫn ghi log |
| Hàng đợi | 1 queue cho mỗi loại rule | 1 mailbox cho mỗi node, concurrency riêng |
| Vòng đời | Session vĩnh viễn, EndCount đếm sai, Infinity() khiến không bao giờ kết thúc | Run cho mỗi sự kiện, kết thúc khi hết message in-flight |
| Timeout | TimeoutSession: 30 bị ép thành 30 nanosecond và không ai đọc | join TTL + run TTL + trần số bước, đều cấu hình được |
| Dữ liệu | map[string]interface{} chia sẻ giữa các nhánh fan-out (data race) | serde_json::Value, deep clone tại điểm fan-out |
| Dừng | Rule.Stop() không bao giờ được gọi | SourceRule::stop được gọi khi gỡ luồng |
Chạy khi phát triển
cargo run -p rule-engine # backend :4550
cd apps/rule-engine/web && npm run dev # UI dev server, proxy /api
cargo test -p rule-engine # testĐăng ký với daemon (daemon thấy port 4550 đã healthy sẽ dùng lại tiến trình của bạn thay vì spawn bản khác):
curl -X POST http://127.0.0.1:18788/api/space/apps/register-local \
-H 'content-type: application/json' \
-d '{"path":"/Users/benji/Projects/SemaClaw/apps/rule-engine"}'Đóng gói: ./scripts/pack.sh → rule-engine-app.zip.
Mô hình
nguồn ──out──▶ ┌────────┐ ──true──▶ ...
│ node │ ──false─▶ ...
──in──────▶ └────────┘ ──error─▶ ...- Chain — đồ thị đã lưu.
ACTIVEthì được nạp và chạy. - Run — một sự kiện chảy qua đồ thị. Kết thúc khi không còn message nào đang bay và không còn barrier nào đang chờ.
- Hop — một bước trong run. Chỉ ghi lại khi bật debug.
- Message —
{ data, meta }.datalà payload phẳng;metalà thông tin kèm theo (nguồn, headers, thời điểm). Biểu thức thấydataở tầng trên cùng vàmetadưới tênmeta_data.
Nhiều cổng vào
Mặc định (opts.join = "any") mỗi message vào node là một lần chạy độc lập — đúng như engine Go. Đổi thành:
"all"— chờ đủ một message trên mỗi cổng vào đang được nối, chạy một lần với{ "<tên cổng>": <data> }"merge"— như trên nhưng deep-merge thành một object
Barrier gom theo (run, node, thế hệ), hoặc theo opts.corrKey nếu muốn gom theo một giá trị nghiệp vụ. Quá joinTimeoutMs thì nhánh bị huỷ và ghi log — không treo im lặng.
Danh mục node
Gọi GET /api/registry (hoặc MCP rule_registry) để lấy danh sách đầy đủ kèm cổng và JSON Schema cấu hình. Nhóm chính:
- Nguồn —
manual,webhook,schedule,telegram-poll - Logic —
conditional,switch,fork,join,merge,trigger-time - Biến đổi —
arithmetic,format,project,delay,split - Lọc có state —
moving-average,kalman - Đích —
http-request,telegram-send,notification,log,mcp-call,senclaw-send - AI —
ai-agent(bridge SenClaw / persona / provider trực tiếp),knowledge
REST
GET /api/status | sức khoẻ + số liệu |
GET /api/registry | danh mục node cho UI |
GET/POST /api/chains | liệt kê / tạo |
GET/PATCH/DELETE /api/chains/:id | chi tiết / sửa metadata / xoá |
PUT /api/chains/:id/graph | thay toàn bộ đồ thị |
POST /api/chains/:id/validate|activate|deactivate|trigger | |
GET /api/chains/:id/runs|logs | lịch sử |
GET /api/runs/:id/hops | trace từng bước |
DELETE /api/chains/:id/state | xoá state của node lọc |
GET /api/events | SSE realtime (hop / log / trạng thái run) |
POST /api/hooks/:webhookId | ingress cho node webhook |
Biến môi trường
| mặc định | ||
|---|---|---|
PORT | 4550 | |
RULE_ENGINE_DATA_DIR | ~/.senclaw/space-app-data/rule-engine | nằm ngoài thư mục cài, vì cài lại zip sẽ xoá sạch app_dir |
RULE_ENGINE_JOIN_TIMEOUT_MS | 60000 | hạn mặc định của barrier |
RULE_ENGINE_MAX_HOPS | 10000 | trần số bước mỗi run, chặn vòng lặp vô tận |
RULE_ENGINE_RUN_TTL_SECS | 900 | run quá hạn bị thu hồi |
SENCLAW_BASE_URL | http://127.0.0.1:18788 | daemon, cho bridge LLM/knowledge |
Giới hạn đã biết
- Bridge
llm.request**không cótemperature** (daemon hard-code 0.2). Nodeai-agentchỉ cho chỉnh nó ở backendprovider(gọi thẳng nhà cung cấp). finish == "length"được coi là lỗi, không phải kết quả — câu trả lời cụt sẽ ra cổngerrorthay vì đi tiếp với JSON gãy.- Bridge
mcp.callcủa core vẫn là stub, nên nodemcp-callPOST thẳng vào/api/mcp/messagecủa app đích. - Nhóm node IoT của Dipper (
input-telemetry,output-model,get-last-model…) chưa có — chúng phụ thuộc bảng device/model của dipper-hub. Xem §10 của design doc.
Declared permissions
{
"network": [
"127.0.0.1"
],
"exec": [
"./rule-engine"
]
}Declared by the publisher, not enforced by SenClaw. The CLI compares this against what you already have installed and asks before anything widens.
Published by
The checkmark means SenClaw confirmed who this publisher is. It says nothing about whether their packages are safe.
About
| Owner | @senclaw |
| Latest | 1.0.0 |
| Downloads (30d) | 0 |
| Repository | github.com/NortonBen/senclaw-app ↗ |
Versions
| Version | Tags | Artifacts | Published |
|---|---|---|---|
1.0.0 | latest | darwin-arm64, linux-x64, win32-x64 | 2026-08-07 |
Artifacts · 1.0.0
| Platform | Format | Signature | File | Size |
|---|---|---|---|---|
darwin-arm64 | zip | unsigned | rule-engine-app.zip | 3543 KB |
linux-x64 | zip | unsigned | rule-engine-app.zip | 3991 KB |
win32-x64 | zip | unsigned | rule-engine-app.zip | 3910 KB |
Unsigned builds require sign-in to download and are not distributed to the auto-updater, because unsigned executables from a new domain get flagged as unsafe. Sign and notarize (macOS) or Authenticode-sign (Windows) to distribute publicly.
Auto-update endpoints
For a Tauri app — add to tauri.conf.json:
"endpoints": ["https://senclaw.bacnd.com/api/v1/updates/tauri/senclaw/rule-engine/{{target}}/{{arch}}/{{current_version}}"]For an electron-updater app — generic provider URL:
https://senclaw.bacnd.com/updates/senclaw/rule-engine/stable
Only signed/notarized artifacts are offered as updates — a client fetches the update without credentials, and unsigned binaries are not publicly downloadable.
Something wrong with this package?
Report this package
Report this package
Tell us what is wrong and a moderator will look at it. Be specific — a report that names a version and a behaviour can be checked in minutes; one that says “looks sketchy” cannot be acted on at all.
Not about this package? Contact us instead. What happens to a report is described in reporting and moderation.
API: GET https://senclaw.bacnd.com/api/v1/packages/senclaw/rule-engine