Skip to content

dynamder/funera

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

76 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Funera

An LLM agent framework for Rust. Build AI agents with tools, skills, middleware, and pluggable LLM backends — all with multi-layered security.

License: MIT Rust

Architecture

┌─────────────────────────────────────────────────────┐
│  funera-orchestrate    high-level builder API       │
│  Agent · AgentRuntime · callbacks · streaming       │
├─────────────────────────────────────────────────────┤
│  funera_core           core engine                  │
│  ReActLoop · Session · EventBus · Middleware        │
│  Security · Provider · Tools · Skills               │
├─────────────────────────────────────────────────────┤
│  builtin_tools         default tool implementations │
│  ReadTool · WriteTool · EditTool · ShellTool        │
└─────────────────────────────────────────────────────┘

Features

  • ReAct loop — iterative tool-calling agent execution with configurable max iterations
  • Pluggable providers — OpenAI and DeepSeek backends with streaming support
  • Tool system — define custom tools by implementing the Tool trait; built-in file I/O and shell
  • Skill system — load prompt templates from YAML-frontmatter Markdown files
  • Middleware pipeline — intercept agent events with inspectors (read-only, parallel) and mutators (pass/modify/block, sequential)
  • Security layer — tool/shell policies, path allowlisting, audit logging, secure API key storage
  • Type-state session — compile-time enforcement of session ownership (Idle / Acquired)

Installation

Add the root crate to your Cargo.toml:

[dependencies]
funera = { git = "https://github.com/dynamder/Funera" }

Features

Feature Default Description
builtin-tools Bundled Read, Write, Edit, Shell tools
deepseek DeepSeek provider
openai OpenAI provider
security Tool policy enforcement, path guards, audit logging
sandbox Kernel-level subprocess isolation (Landlock/Seatbelt/Token)
middleware Event interception pipeline
skill Skill loading and prompt injection

Quick Start

One-shot query

use funera::{Agent, AgentRuntime, DeepSeekProvider};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let runtime = AgentRuntime::<DeepSeekProvider>::builder()
        .api_key(std::env::var("DEEPSEEK_API_KEY")?)
        .model("deepseek-v4-flash")
        .build()?;

    let agent = Agent::builder()
        .system_prompt("You are a helpful assistant.")
        .build();

    let resp = agent.fire("Hello!", &runtime).await?;
    println!("{}", resp.content);
    Ok(())
}

Streaming with callbacks

use funera::{Agent, AgentEvent, AgentRuntime, DeepSeekProvider};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let runtime = AgentRuntime::<DeepSeekProvider>::builder()
    .api_key(std::env::var("DEEPSEEK_API_KEY")?)
    .model("deepseek-v4-flash")
    .build()?;

let agent = Agent::builder()
    .on_token(|t| print!("{t}"))
    .build();

let mut rx = agent.fire_stream("Explain Rust ownership", &runtime).await?;
while let Some(event) = rx.recv().await {
    if let AgentEvent::Text(t) = event {
        print!("{t}");
    }
}
Ok(())
}

Multi-turn conversation

let runtime = AgentRuntime::<DeepSeekProvider>::builder()
    .api_key(std::env::var("DEEPSEEK_API_KEY")?)
    .model("deepseek-v4-flash")
    .build()?;

let agent = Agent::builder()
    .system_prompt("You are helpful.")
    .build();

let handle = agent.send("Hi, I'm Alice.", runtime).await?;
let (runtime, _resp) = handle.await?;
let handle = agent.send("What's my name?", runtime).await?;
let (_runtime, _resp) = handle.await?;

Custom tool

use async_trait::async_trait;
use funera::core::re_act::tool::{Tool, ToolCallError};
use serde_json::{json, Value as JsonValue};

struct Calculator;

#[async_trait]
impl Tool for Calculator {
    fn name(&self) -> &str { "calculator" }
    fn description(&self) -> &str { "Evaluate a math expression" }
    fn schema(&self) -> JsonValue {
        json!({
            "type": "function",
            "function": {
                "name": "calculator",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "expression": { "type": "string" }
                    },
                    "required": ["expression"]
                }
            }
        })
    }
    async fn execute(&self, args: JsonValue) -> Result<String, ToolCallError> {
        let expr = args["expression"].as_str().unwrap_or("");
        Ok(format!("TODO: compute {expr}"))
    }
}

// Register it:
let runtime = AgentRuntime::<DeepSeekProvider>::builder()
    .api_key(std::env::var("DEEPSEEK_API_KEY")?)
    .model("deepseek-v4-flash")
    .with_tool_instance(Box::new(Calculator))
    .build()?;

Security configuration

Requires the security feature (and optionally builtin-tools, sandbox):

use funera::{Agent, AgentRuntime, DeepSeekProvider, ToolPolicy, ShellPolicy};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let runtime = AgentRuntime::<DeepSeekProvider>::builder()
        .api_key(std::env::var("DEEPSEEK_API_KEY")?)
        .model("deepseek-v4-flash")
        .with_builtin_tools()
        .with_tool_policy(ToolPolicy {
            denied_tools: ["shell".into()].into_iter().collect(),
            shell_policy: Some(ShellPolicy::with_allowed(
                vec!["git".into(), "cargo".into()],
            )),
            ..Default::default()
        })
        .build()?;

    let agent = Agent::builder().build();
    let resp = agent.fire("List the git log.", &runtime).await?;
    println!("{}", resp.content);
    Ok(())
}

Project structure

funera/
├── funera_core/          Core agent engine
│   └── src/
│       ├── chat/         Message types, session actor
│       ├── env.rs        Shared runtime environment
│       ├── event_bus/    Token, React, EnvState, Tool buses
│       ├── middleware.rs  Event interception pipeline
│       ├── provider/     OpenAI & DeepSeek backends
│       ├── re_act/       ReAct loop, Tool trait, Skill system
│       └── security/     Policies, path guard, audit, secrets
├── funera-orchestrate/   High-level builder API
│   ├── src/
│   │   ├── agent.rs      Agent & AgentBuilder
│   │   ├── runtime.rs    AgentRuntime & AgentRuntimeBuilder
│   │   ├── event.rs      AgentEvent enum
│   │   ├── dispatcher.rs  Callback dispatch
│   │   └── send_handle.rs Ownership handles
│   └── examples/         Example programs
├── builtin_tools/        Default tool implementations
│   └── src/
│       ├── read.rs       ReadTool (file/dir, hashline output)
│       ├── write.rs      WriteTool (auto parent dirs)
│       ├── edit.rs       EditTool (hashline-anchored editing)
│       └── shell.rs      ShellTool (cross-platform, timeout)
└── tui/                  TUI frontend (stub)

License

MIT — see the repository for details.

About

A flexible, modularized and easy-to-use agent framework.

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages