mirror of
https://github.com/RightNow-AI/openfang.git
synced 2026-07-30 23:05:08 +00:00
Open-source Agent OS built in Rust. - 14 crates, 1,767+ tests, zero clippy warnings - 7 autonomous Hands (Clip, Lead, Collector, Predictor, Researcher, Twitter, Browser) - 16 security systems (WASM sandbox, Merkle audit trail, taint tracking, Ed25519 signing, SSRF protection, secret zeroization, HMAC-SHA256 mutual auth, and more) - 30 pre-built agents across 4 performance tiers - 40 channel adapters (Telegram, Discord, Slack, WhatsApp, Teams, and 35 more) - 38 built-in tools + MCP client/server + A2A protocol - 26 LLM providers with intelligent routing and cost tracking - 60+ bundled skills with FangHub marketplace - Tauri 2.0 native desktop app - 140+ REST/WS/SSE API endpoints with Alpine.js dashboard - OpenAI-compatible /v1/chat/completions endpoint - One-command install, production-ready
124 lines
4.8 KiB
Markdown
124 lines
4.8 KiB
Markdown
# OpenFang — Agent Instructions
|
|
|
|
## Project Overview
|
|
OpenFang is an open-source Agent Operating System written in Rust (14 crates).
|
|
- Config: `~/.openfang/config.toml`
|
|
- Default API: `http://127.0.0.1:4200`
|
|
- CLI binary: `target/release/openfang.exe` (or `target/debug/openfang.exe`)
|
|
|
|
## Build & Verify Workflow
|
|
After every feature implementation, run ALL THREE checks:
|
|
```bash
|
|
cargo build --workspace --lib # Must compile (use --lib if exe is locked)
|
|
cargo test --workspace # All tests must pass (currently 1744+)
|
|
cargo clippy --workspace --all-targets -- -D warnings # Zero warnings
|
|
```
|
|
|
|
## MANDATORY: Live Integration Testing
|
|
**After implementing any new endpoint, feature, or wiring change, you MUST run live integration tests.** Unit tests alone are not enough — they can pass while the feature is actually dead code. Live tests catch:
|
|
- Missing route registrations in server.rs
|
|
- Config fields not being deserialized from TOML
|
|
- Type mismatches between kernel and API layers
|
|
- Endpoints that compile but return wrong/empty data
|
|
|
|
### How to Run Live Integration Tests
|
|
|
|
#### Step 1: Stop any running daemon
|
|
```bash
|
|
tasklist | grep -i openfang
|
|
taskkill //PID <pid> //F
|
|
# Wait 2-3 seconds for port to release
|
|
sleep 3
|
|
```
|
|
|
|
#### Step 2: Build fresh release binary
|
|
```bash
|
|
cargo build --release -p openfang-cli
|
|
```
|
|
|
|
#### Step 3: Start daemon with required API keys
|
|
```bash
|
|
GROQ_API_KEY=<key> target/release/openfang.exe start &
|
|
sleep 6 # Wait for full boot
|
|
curl -s http://127.0.0.1:4200/api/health # Verify it's up
|
|
```
|
|
The daemon command is `start` (not `daemon`).
|
|
|
|
#### Step 4: Test every new endpoint
|
|
```bash
|
|
# GET endpoints — verify they return real data, not empty/null
|
|
curl -s http://127.0.0.1:4200/api/<new-endpoint>
|
|
|
|
# POST/PUT endpoints — send real payloads
|
|
curl -s -X POST http://127.0.0.1:4200/api/<endpoint> \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"field": "value"}'
|
|
|
|
# Verify write endpoints persist — read back after writing
|
|
curl -s -X PUT http://127.0.0.1:4200/api/<endpoint> -d '...'
|
|
curl -s http://127.0.0.1:4200/api/<endpoint> # Should reflect the update
|
|
```
|
|
|
|
#### Step 5: Test real LLM integration
|
|
```bash
|
|
# Get an agent ID
|
|
curl -s http://127.0.0.1:4200/api/agents | python3 -c "import sys,json; print(json.load(sys.stdin)[0]['id'])"
|
|
|
|
# Send a real message (triggers actual LLM call to Groq/OpenAI)
|
|
curl -s -X POST "http://127.0.0.1:4200/api/agents/<id>/message" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"message": "Say hello in 5 words."}'
|
|
```
|
|
|
|
#### Step 6: Verify side effects
|
|
After an LLM call, verify that any metering/cost/usage tracking updated:
|
|
```bash
|
|
curl -s http://127.0.0.1:4200/api/budget # Cost should have increased
|
|
curl -s http://127.0.0.1:4200/api/budget/agents # Per-agent spend should show
|
|
```
|
|
|
|
#### Step 7: Verify dashboard HTML
|
|
```bash
|
|
# Check that new UI components exist in the served HTML
|
|
curl -s http://127.0.0.1:4200/ | grep -c "newComponentName"
|
|
# Should return > 0
|
|
```
|
|
|
|
#### Step 8: Cleanup
|
|
```bash
|
|
tasklist | grep -i openfang
|
|
taskkill //PID <pid> //F
|
|
```
|
|
|
|
### Key API Endpoints for Testing
|
|
| Endpoint | Method | Purpose |
|
|
|----------|--------|---------|
|
|
| `/api/health` | GET | Basic health check |
|
|
| `/api/agents` | GET | List all agents |
|
|
| `/api/agents/{id}/message` | POST | Send message (triggers LLM) |
|
|
| `/api/budget` | GET/PUT | Global budget status/update |
|
|
| `/api/budget/agents` | GET | Per-agent cost ranking |
|
|
| `/api/budget/agents/{id}` | GET | Single agent budget detail |
|
|
| `/api/network/status` | GET | OFP network status |
|
|
| `/api/peers` | GET | Connected OFP peers |
|
|
| `/api/a2a/agents` | GET | External A2A agents |
|
|
| `/api/a2a/discover` | POST | Discover A2A agent at URL |
|
|
| `/api/a2a/send` | POST | Send task to external A2A agent |
|
|
| `/api/a2a/tasks/{id}/status` | GET | Check external A2A task status |
|
|
|
|
## Architecture Notes
|
|
- **Don't touch `openfang-cli`** — user is actively building the interactive CLI
|
|
- `KernelHandle` trait avoids circular deps between runtime and kernel
|
|
- `AppState` in `server.rs` bridges kernel to API routes
|
|
- New routes must be registered in `server.rs` router AND implemented in `routes.rs`
|
|
- Dashboard is Alpine.js SPA in `static/index_body.html` — new tabs need both HTML and JS data/methods
|
|
- Config fields need: struct field + `#[serde(default)]` + Default impl entry + Serialize/Deserialize derives
|
|
|
|
## Common Gotchas
|
|
- `openfang.exe` may be locked if daemon is running — use `--lib` flag or kill daemon first
|
|
- `PeerRegistry` is `Option<PeerRegistry>` on kernel but `Option<Arc<PeerRegistry>>` on `AppState` — wrap with `.as_ref().map(|r| Arc::new(r.clone()))`
|
|
- Config fields added to `KernelConfig` struct MUST also be added to the `Default` impl or build fails
|
|
- `AgentLoopResult` field is `.response` not `.response_text`
|
|
- CLI command to start daemon is `start` not `daemon`
|
|
- On Windows: use `taskkill //PID <pid> //F` (double slashes in MSYS2/Git Bash)
|