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?; agent.fire("What is Rust?", &powerful).await?; let (_fast, _) = agent.send("Tell me more", fast).await?.await?; # 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]