Some checks failed
CI / Check / macos-latest (push) Has been cancelled
CI / Check / ubuntu-latest (push) Has been cancelled
CI / Check / windows-latest (push) Has been cancelled
CI / Test / macos-latest (push) Has been cancelled
CI / Test / ubuntu-latest (push) Has been cancelled
CI / Test / windows-latest (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Security Audit (push) Has been cancelled
CI / Secrets Scan (push) Has been cancelled
CI / Install Script Smoke Test (push) Has been cancelled
11 KiB
11 KiB
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(ortarget/debug/openfang.exe)
Architecture Overview
Crate Structure (14 crates)
openfang-types # 基础类型 (零依赖,被所有 crate 使用)
openfang-memory # 存储层 (SQLite + 向量 + 知识图谱)
openfang-runtime # Agent 运行时 (LLM 驱动 + 工具执行 + WASM)
openfang-kernel # 核心协调器 (Registry + Scheduler + EventBus)
openfang-api # HTTP 服务 (Axum + WebSocket + SSE)
openfang-wire # P2P 协议 (OFP + HMAC 认证)
openfang-channels # 消息渠道 (40+ 适配器)
openfang-skills # 技能系统 (4 运行时 + 60 技能)
openfang-hands # 自主能力包 (7 预构建 Agent)
openfang-extensions # 集成系统 (25+ MCP 模板)
openfang-cli # 命令行 (14+ 子命令)
openfang-desktop # 桌面应用 (Tauri 2.0)
openfang-migrate # 迁移工具 (OpenClaw 导入)
Dependency Rules
openfang-types不能依赖任何内部 crateopenfang-kernel依赖openfang-runtime,openfang-memoryopenfang-api依赖openfang-kernel- 禁止循环依赖 - 使用
KernelHandletrait 解决 runtime ↔ kernel 循环
Key Design Patterns
- KernelHandle Trait: 解决 runtime ↔ kernel 循环依赖
- Plugin Architecture: Skills/Hands/Extensions 可扩展
- Event-Driven: EventBus 发布订阅模式
- Dual Persistence: 内存 (DashMap) + SQLite 双写
Build & Verify Workflow
After every feature implementation, run ALL THREE checks:
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 Test Checklist
- Route registered in
server.rsrouter - Handler implemented in
routes.rs - GET returns real data (not empty/null)
- POST/PUT persists data (read back to verify)
- LLM integration works (real API call)
- Side effects tracked (metering/budget)
- Dashboard UI shows new components
Quick Integration Test Script
# Stop any running daemon
tasklist | grep -i openfang && taskkill //PID <pid> //F
sleep 3
# Build and start
cargo build --release -p openfang-cli
GROQ_API_KEY=<key> target/release/openfang.exe start &
sleep 6
# Verify health
curl -s http://127.0.0.1:4200/api/health
# Test your new endpoint
curl -s http://127.0.0.1:4200/api/<your-endpoint>
# Cleanup
taskkill //PID <pid> //F
Persistence Rules (CRITICAL)
Rule 1: Dual Write Pattern
所有 Agent 修改操作必须同时更新:
- 内存:
registry.xxx()更新 DashMap - SQLite:
memory.save_agent(&entry)持久化
// ✅ 正确: Kernel 层包装方法
pub fn set_agent_mode(&self, agent_id: AgentId, mode: AgentMode) -> KernelResult<()> {
self.registry.set_mode(agent_id, mode)?; // 内存
if let Some(entry) = self.registry.get(agent_id) {
let _ = self.memory.save_agent(&entry); // SQLite
}
Ok(())
}
// ❌ 错误: 直接调用 registry (不持久化)
state.kernel.registry.set_mode(agent_id, mode)
Rule 2: 使用 Kernel 包装方法
在 API 层 (routes.rs) 始终调用 kernel 方法,不要直接调用 registry:
| ❌ 错误调用 | ✅ 正确调用 |
|---|---|
registry.set_mode() |
kernel.set_agent_mode() |
registry.set_state() |
kernel.set_agent_state() |
registry.update_identity() |
kernel.update_agent_identity() |
registry.update_name() |
kernel.update_agent_name() |
registry.update_description() |
kernel.update_agent_description() |
Rule 3: 已持久化的操作
以下操作已正确实现持久化,可直接使用:
kernel.update_agent_model()kernel.update_agent_system_prompt()kernel.set_agent_skills()kernel.set_agent_mcp_servers()kernel.kill_agent()(调用memory.remove_agent())
API Development Rules
Rule 1: Route Registration
新路由必须在两处注册:
server.rs- 添加到 routerroutes.rs- 实现 handler 函数
// server.rs
.route("/api/agents/{id}/custom", axum::routing::get(routes::get_custom).put(routes::set_custom))
// routes.rs
pub async fn get_custom(...) -> impl IntoResponse { ... }
pub async fn set_custom(...) -> impl IntoResponse { ... }
Rule 2: AppState Access
// AppState 结构
pub struct AppState {
pub kernel: Arc<OpenFangKernel>,
pub started_at: Instant,
pub peer_registry: Option<Arc<PeerRegistry>>, // 注意: Option<Arc<...>>
pub bridge_manager: tokio::sync::Mutex<Option<BridgeManager>>,
pub channels_config: tokio::sync::RwLock<ChannelsConfig>,
pub shutdown_notify: Arc<tokio::sync::Notify>,
}
Rule 3: Error Response Format
// 统一错误响应格式
(StatusCode::NOT_FOUND, Json(serde_json::json!({"error": "Agent not found"})))
(StatusCode::BAD_REQUEST, Json(serde_json::json!({"error": "Invalid input"})))
(StatusCode::CONFLICT, Json(serde_json::json!({"error": "Name already exists"})))
Rule 4: Success Response Format
// 统一成功响应格式
(StatusCode::OK, Json(serde_json::json!({"status": "ok", "agent_id": id})))
(StatusCode::CREATED, Json(serde_json::json!({"id": new_id, "name": name})))
Config & Types Rules
Rule 1: New Config Fields
添加新配置字段需要:
- 在 struct 中添加字段
- 添加
#[serde(default)] - 在
Defaultimpl 中添加默认值 - 确保
Serialize + Deserializederived
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KernelConfig {
// ... existing fields ...
#[serde(default)]
pub new_field: String, // 必须有 #[serde(default)]
}
impl Default for KernelConfig {
fn default() -> Self {
Self {
// ... existing defaults ...
new_field: String::new(), // 必须在 Default 中
}
}
}
Rule 2: Type Definitions
新类型定义放在正确的 crate:
- 共享类型:
openfang-types/ - API 特有:
openfang-api/src/ - Kernel 特有:
openfang-kernel/src/
Security Rules
16-Layer Security Model
- Capability-based access control
- Path traversal protection
- SSRF protection (私有 IP 阻断)
- Ed25519 signed manifests
- Merkle hash chain audit
- Information flow taint tracking
- HMAC-SHA256 mutual auth
- API key Bearer auth
- GCRA rate limiter
- Security headers (CSP/HSTS/X-Frame-Options)
- Secret zeroization
- Subprocess environment isolation
- Health endpoint redaction
- Loop guard with SHA256 detection
- Session repair
- Circuit breaker thresholds
Security Checklist for New Features
- 输入验证 (sanitize user input)
- 权限检查 (capability-based)
- 路径安全 (no path traversal)
- SSRF 防护 (block private IPs)
- 敏感信息脱敏 (logs, health endpoint)
Common Gotchas
Build Issues
| 问题 | 解决方案 |
|---|---|
openfang.exe locked |
使用 --lib flag 或 kill daemon |
| cargo not found | 检查 PATH 环境变量 |
| clippy warnings | 所有 warning 必须修复 (-D warnings) |
Type Mismatches
| 问题 | 解决方案 |
|---|---|
PeerRegistry 类型 |
kernel: Option<PeerRegistry>, AppState: Option<Arc<PeerRegistry>> |
AgentLoopResult.response |
不是 .response_text |
| UUID parsing | 使用 .parse::<AgentId>() |
Windows-Specific
| 问题 | 解决方案 |
|---|---|
| taskkill syntax | taskkill //PID <pid> //F (double slashes) |
| Path separators | 使用 / 或 std::path::PathBuf |
| Sleep command | sleep 在 Git Bash/MSYS2 中可用 |
CLI Commands
- 启动守护进程:
openfang start(不是daemon) - 停止守护进程:
taskkill //PID <pid> //F
Frontend Rules (Alpine.js SPA)
File Locations
- HTML:
crates/openfang-api/static/index_body.html - JS:
crates/openfang-api/static/js/ - CSS:
crates/openfang-api/static/css/
Adding New UI Components
- 在
index_body.html添加 HTML 结构 - 在对应的 JS 文件中添加 Alpine.js data/methods
- 在
api.js中添加 API 调用方法
Alpine.js Pattern
// 在页面组件中
function myPage() {
return {
data: [],
loading: false,
async loadData() {
this.loading = true;
try {
this.data = await OpenFangAPI.getData();
} finally {
this.loading = false;
}
},
init() {
this.loadData();
}
}
}
Testing Rules
Test Categories
- Unit Tests:
#[cfg(test)] mod tests { ... }在各模块内 - Integration Tests:
tests/目录 - Live Tests: 运行 daemon 后 curl 测试
Test Requirements
- 所有新功能必须有测试
- 测试覆盖率目标: 90%+
- 测试名称:
test_<功能>_<场景>
Test Pattern
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_feature_success() {
// Arrange
let store = setup();
// Act
let result = store.do_something();
// Assert
assert!(result.is_ok());
}
#[test]
fn test_feature_error_case() {
// Test error handling
}
}
LLM Provider Support
Supported Providers (30+)
- Anthropic (Claude)
- OpenAI (GPT)
- Google (Gemini)
- Groq, OpenRouter, DeepSeek, Together, Mistral, Fireworks
- Ollama, vLLM, LM Studio (local)
- Perplexity, Cohere, AI21, Cerebras, SambaNova
- HuggingFace, xAI, Replicate
- GitHub Copilot, Codex, Claude Code CLI
- 中国提供商: 智谱 GLM, 百炼, Moonshot, Qwen, Minimax, 千帆
Adding New Provider
- 在
openfang-types/src/model_catalog.rs添加 BASE_URL 常量 - 在
openfang-runtime/src/model_catalog.rs添加模型和提供商信息 - 在
openfang-runtime/src/drivers/mod.rs添加provider_defaults()条目 - 添加测试用例
Code Style Guidelines
Rust Conventions
- 使用
use导入,避免完整路径 - 错误处理使用
Result<T, E>和?操作符 - 使用
tracingcrate 进行日志记录 - 异步代码使用
tokio运行时
Naming Conventions
- 函数/变量:
snake_case - 类型/Trait:
PascalCase - 常量:
SCREAMING_SNAKE_CASE - 模块:
snake_case
Documentation
- 公共 API 必须有文档注释 (
///) - 复杂逻辑必须有注释说明
- 使用
//!作为模块级文档
Key Files Quick Reference
| 文件 | 用途 |
|---|---|
crates/openfang-kernel/src/kernel.rs |
核心协调器,所有子系统的入口 |
crates/openfang-kernel/src/registry.rs |
Agent 内存注册表 (DashMap) |
crates/openfang-memory/src/structured.rs |
Agent SQLite 持久化 |
crates/openfang-api/src/server.rs |
HTTP 路由注册 |
crates/openfang-api/src/routes.rs |
HTTP 处理函数 |
crates/openfang-api/src/ws.rs |
WebSocket 处理 |
crates/openfang-runtime/src/drivers/mod.rs |
LLM 提供商驱动 |
crates/openfang-types/src/model_catalog.rs |
模型/提供商常量 |
Current Date
Today's date is 2026-03-01.