开发指南

LibreFang 开发环境设置和贡献指南。


开发环境

前置要求

  • Rust 1.75+
  • Node.js 18+ (用于桌面应用)
  • pnpm 8+ (用于文档站点)

克隆仓库

git clone https://github.com/librefang/librefang.git
cd librefang

构建

# 构建整个工作空间
cargo build --workspace

# 构建 CLI
cargo build -p librefang-cli

# 构建桌面应用
cargo build -p librefang-desktop

# 构建 React Dashboard(Web UI 所需)
cd crates/librefang-api/dashboard-react
npm install
npm run build

测试

# 运行所有测试
cargo test --workspace

# 运行特定 crate
cargo test -p librefang-kernel

# 运行文档测试
cargo test --doc

代码检查

# 必须零警告
cargo clippy --workspace --all-targets -- -D warnings

# 格式化检查
cargo fmt --all -- --check

项目结构

librefang/
├── Cargo.lock
├── Cargo.toml
├── crates/
   ├── librefang-cli/          # CLI 工具
   ├── librefang-api/         # REST API 服务器
   ├── librefang-kernel/      # 核心内核
   ├── librefang-runtime/     # Agent 运行时
   ├── librefang-memory/      # 内存子系统
   ├── librefang-types/       # 共享类型
   ├── librefang-channels/    # 通道适配器
   ├── librefang-skills/      # 技能系统
   ├── librefang-hands/       # Hands 系统
   ├── librefang-wire/        # P2P 协议
   ├── librefang-desktop/     # 桌面应用
   ├── librefang-migrate/     # 迁移工具
   └── librefang-extensions/   # 扩展
├── xtask/                      # 构建脚本
├── docs/                       # 项目文档
└── scripts/                    # 辅助脚本

添加新通道

1. 创建通道模块

// crates/librefang-channels/src/my_channel.rs

use async_trait::async_trait;
use std::pin::Pin;
use futures::Stream;
use crate::types::{ChannelAdapter, ChannelContent, ChannelMessage, ChannelStatus, ChannelType, ChannelUser};

pub struct MyChannel {
    // 特定通道的字段(如 API 客户端、配置等)
}

#[async_trait]
impl ChannelAdapter for MyChannel {
    fn name(&self) -> &str {
        "my_channel"
    }

    fn channel_type(&self) -> ChannelType {
        ChannelType::Custom("my_channel".to_string())
    }

    async fn start(
        &self,
    ) -> Result<
        Pin<Box<dyn Stream<Item = ChannelMessage> + Send>>,
        Box<dyn std::error::Error + Send + Sync>,
    > {
        // 返回传入消息的流
        todo!()
    }

    async fn send(
        &self,
        _user: &ChannelUser,
        _content: ChannelContent,
    ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        // 向用户发送响应
        Ok(())
    }

    async fn stop(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        Ok(())
    }
}

2. 注册通道

通道适配器通过 librefang-api/src/server.rs 中的 BridgeManager 注册, 调用 bridge_manager.add_adapter(Arc::new(MyChannel::new(config))) 即可。 每个适配器都通过 crates/librefang-channels/Cargo.toml 中的 Cargo feature flag (channel-my-channel)进行控制。

// crates/librefang-channels/src/lib.rs — 添加 feature-gated 模块
#[cfg(feature = "channel-my-channel")]
pub mod my_channel;

3. 添加配置

// crates/librefang-types/src/config.rs

#[derive(Debug, Clone, Deserialize)]
pub struct MyChannelConfig {
    pub api_key_env: String,
    pub allowed_users: Option<Vec<String>>,
}

添加新技能

1. 创建技能结构

# skills/my-skill/skill.toml
name = "my-skill"
version = "1.0.0"
description = "My custom skill"

[runtime]
type = "python"
entrypoint = "main.py"

[tools]
provided = ["my_tool"]

[requirements]
packages = ["requests"]

2. 实现代码

# skills/my-skill/main.py

def my_tool(param: str) -> str:
    """My custom tool description"""
    # 实现逻辑
    return f"Result: {param}"

# 注册工具
TOOLS = [my_tool]

3. 编译技能

# 技能会自动编译到二进制中
cargo build --workspace

添加新工具

1. 定义工具

// crates/librefang-runtime/src/tools/mod.rs

use crate::tool::{Tool, ToolResult};

pub struct MyTool;

impl Tool for MyTool {
    fn name(&self) -> &str {
        "my_tool"
    }

    fn description(&self) -> &str {
        "My custom tool description"
    }

    async fn execute(&self, params: Value) -> ToolResult {
        // 实现工具逻辑
        Ok(Value::String("result".to_string()))
    }
}

2. 注册工具

// crates/librefang-runtime/src/lib.rs

pub fn register_tools(registry: &mut ToolRegistry) {
    registry.register(MyTool::new());
}

添加新 LLM 提供商

1. 实现驱动

// crates/librefang-runtime/src/llm/my_provider.rs

use crate::llm::{LlmDriver, LlmResponse, LlmError};

pub struct MyProvider {
    api_key: String,
    base_url: String,
}

#[async_trait]
impl LlmDriver for MyProvider {
    async fn complete(&self, prompt: &str) -> Result<LlmResponse, LlmError> {
        // 调用 API
        Ok(LlmResponse {
            text: "response".to_string(),
            tokens: 100,
        })
    }
}

2. 添加到模型目录

// crates/librefang-types/src/models.rs

pub fn get_provider(name: &str) -> Option<Box<dyn LlmDriver>> {
    match name {
        "my_provider" => Some(Box::new(MyProvider::new())),
        _ => None,
    }
}

代码风格

Rust 规范

  • 使用 cargo fmt 格式化
  • 使用 cargo clippy 检查
  • 遵循 Rust 命名约定
  • 添加文档注释 (///)

提交规范

# 格式: <type>(<scope>): <description>

git commit -m "feat(kernel): add new scheduling algorithm"
git commit -m "fix(channels): resolve Slack rate limit"
git commit -m "docs(api): update endpoint documentation"
git commit -m "test(runtime): add tool execution tests"

类型

类型说明
feat新功能
fixBug 修复
docs文档
style格式
refactor重构
test测试
chore维护

测试

单元测试

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_my_function() {
        assert_eq!(my_function(2), 4);
    }
}

集成测试

#[tokio::test]
async fn test_agent_spawn() {
    let kernel = Kernel::new().await;
    let agent = kernel.spawn("test-agent").await;
    assert!(agent.is_running());
}

基准测试

#[tokio::bench]
async fn benchmark_llm_call(b: &mut Bencher) {
    b.iter(|| {
        runtime.block_on(llm.complete("test prompt"))
    })
}

调试

日志

use tracing::{info, warn, error};

info!("Starting agent {}", agent_id);
warn!("Rate limit exceeded for channel {}", channel_id);
error!("Failed to connect to provider: {}", error);

调试模式

# 启用详细日志
RUST_LOG=debug cargo run

# 只看特定模块
RUST_LOG=librefang_kernel=trace cargo run

性能分析

# CPU  profiling
cargo flamegraph --bin librefang-cli -- start

# 内存分析
cargo leptos --bin librefang-cli -- start

发布

版本规则

LibreFang 使用 Calendar VersioningYYYY.M.DDHH

类型格式示例说明
稳定版YYYY.M.DDHH2026.3.2314发布日期 + 小时
BetaYYYY.M.DDHH-betaN2026.3.2314-beta1测试预发布
RCYYYY.M.DDHH-rcN2026.3.2314-rc1发布候选
LTSYYYY.M.PATCH-lts2026.3.0-lts长期支持版本

发布流程

所有发布通过 cargo xtask release 完成:

cargo xtask release
#   1) stable  -> 2026.3.2314
#   2) beta    -> 2026.3.2314-beta1
#   3) rc      -> 2026.3.2314-rc1
#   4) lts     -> 2026.3.0-lts

该命令自动完成:

  • 从 git 历史生成 CHANGELOG
  • 同步版本号到 Cargo.toml、package.json、setup.py
  • 构建 React 面板
  • 创建 git tag 并推送
  • 创建版本 bump 的 PR

使用 --dry-run 预览而不做任何修改:

cargo xtask release --dry-run --version "2026.3.0-lts"

LTS 长期支持版本

LTS 版本只接受安全修复和 bug 修复,不加新功能。

版本格式:

v2026.3.0-lts 初始 LTS
v2026.3.1-lts 补丁 1(bug 修复)
v2026.3.2-lts 补丁 2(安全修复)

创建 LTS 版本:

# 在 main 分支上,选择选项 4
cargo xtask release

CI 自动完成:

  • 从 tag 创建 release/2026.3 分支
  • 设置分支保护(需要 PR 审查)
  • Docker 镜像打 :lts 标签
  • GitHub Release 标记为 LTS

发布 LTS 补丁:

# 切换到 LTS 分支
git checkout release/2026.3

# 从 main 挑选修复
git cherry-pick <commit-sha>

# 发布补丁(自动递增补丁号)
cargo xtask release --lts-patch

规则:

  • 只 cherry-pick 修复,不引入新功能
  • 每个补丁必须通过 release/ 分支上的 PR 审查
  • LTS 分支维护到下一个 LTS 版本发布为止
  • Docker :lts 标签始终指向最新的 LTS 版本

贡献

贡献流程

  1. Fork 仓库
  2. 创建特性分支 (git checkout -b feature/my-feature)
  3. 提交更改 (git commit -m "feat: add my feature")
  4. 推送分支 (git push origin feature/my-feature)
  5. 创建 Pull Request

代码审查

  • 确保 cargo clippy 无警告
  • 确保 cargo test 通过
  • 添加测试覆盖新代码
  • 更新文档

行为准则

  • 尊重他人
  • 欢迎新手
  • 专业沟通
  • 接受建设性批评