funera-orchestrate 0.2.0

Easy-to-use orchestration layer for funera-core — build LLM agents with a simple builder API
Documentation

funera-orchestrate

Easy-to-use orchestration layer for [funera-core].

This crate provides a high-level agent API (Agent) and a runtime container (AgentRuntime) that together let you integrate funera's LLM agent runtime into your own projects with minimal boilerplate.

Features

Feature Default Description
deepseek DeepSeek provider
openai OpenAI provider
tool Tool system (trait, registry, executor)
funera-builtin-tools Built-in tools (Read, Write, Edit, Shell)
security Tool policy enforcement
middleware Event interception pipeline (Inspector + Mutator)
skill Skill loading and prompt injection
sandbox Kernel-level subprocess isolation

Quick Start

use funera_orchestrate::{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(())
}

Core Concepts

Concept Type Description
Runtime [AgentRuntime] Shared infrastructure + conversation session
Agent [Agent] Behavioural config (system prompt, callbacks)
One-shot [Agent::fire] Temporary session, discarded after call
Multi-turn [Agent::send] Persistent session across calls
Streaming fire_stream / send_stream Token-by-token streaming

Examples

One-shot query with stream

# use funera_orchestrate::{Agent, AgentEvent, AgentRuntime, DeepSeekProvider};
# async fn example() -> 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's ownership model", &runtime).await?;
while let Some(event) = rx.recv().await {
    if let AgentEvent::Text(t) = event {
        print!("{t}");
    }
}
# Ok(())
# }

Multi-turn conversation with callbacks

# use funera_orchestrate::{Agent, AgentRuntime, DeepSeekProvider};
# async fn example() -> 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 helpful.")
    .on_tool_call(|name, _| eprintln!("[tool] {name}"))
    .on_turn_start(|| eprintln!("--- turn ---"))
    .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?;
# Ok(())
# }

Switching models on the same provider

# use funera_orchestrate::{Agent, AgentRuntime, DeepSeekProvider};
# async fn example() -> Result<(), Box<dyn std::error::Error>> {
let fast = AgentRuntime::<DeepSeekProvider>::builder()
    .api_key(std::env::var("DEEPSEEK_API_KEY")?)
    .model("deepseek-v4-flash")
    .build()?;

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

let agent = Agent::builder().build();

let (fast, _) = agent.send("Hello", fast).await?.await?;              // fast model
agent.fire("What is Rust?", &powerful).await?;                        // powerful model (temp)
let (_fast, _) = agent.send("Tell me more", fast).await?.await?;       // back to fast
# Ok(())
# }

Security configuration

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

# use funera_orchestrate::{AgentRuntime, DeepSeekProvider, ToolPolicy, ShellPolicy};
# fn example() -> 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()?;
# Ok(())
# }

Module Structure

  • [runtime] — [AgentRuntimeBuilder] and [AgentRuntime]
  • [agent] — [AgentBuilder] and [Agent]
  • [dispatcher] — Event bus subscription and callback dispatch
  • [event] — [AgentEvent] enum
  • [response] — [ChatResponse] and [ToolCallInfo]
  • [error] — [OrchestrateError]