Rust SDK
Start here
| Goal | Guide |
|---|---|
| Run a workflow | Run your first workflow |
| Write a worker | Write your first worker |
| Build an agent | Coming soon |
Featured examples
| Category | Maintained upstream example |
|---|---|
| Workflow and worker | Examples |
| Agentic workflow | Agentic workflow examples |
| API journey | Not currently maintained upstream |
The agentic-workflow row covers SDK examples that orchestrate LLMs or tools. It is separate from the SDK-authored Conductor Agent quickstart, which is coming soon for this SDK.
Connect to Conductor
For local OSS, set CONDUCTOR_SERVER_URL=http://localhost:8080/api.
For Orkes Developer Edition, set CONDUCTOR_SERVER_URL=https://developer.orkescloud.com/api, CONDUCTOR_AUTH_KEY, and CONDUCTOR_AUTH_SECRET. Keep credentials out of source control.
This SDK reads these environment variables when constructing its standard client configuration.
Install the SDK
Add the following to your Cargo.toml:
For the #[worker] macro (similar to Python's @worker_task decorator):
[dependencies]
conductor = { version = "VERSION", features = ["macros"] }
conductor-macros = "VERSION"
tokio = { version = "1", features = ["full"] }
60-Second Quickstart
Step 1: Create a workflow
Workflows are definitions that reference task types (e.g. a SIMPLE task called greet). We'll build a workflow called
greetings that runs one task and returns its output.
use conductor::models::{WorkflowDef, WorkflowTask};
fn greetings_workflow() -> WorkflowDef {
WorkflowDef::new("greetings")
.with_version(1)
.with_task(
WorkflowTask::simple("greet", "greet_ref")
.with_input_param("name", "${workflow.input.name}")
)
.with_output_param("result", "${greet_ref.output.result}")
}
Step 2: Write worker
Workers are Rust functions decorated with #[worker] that poll Conductor for tasks and execute them.
use conductor_macros::worker;
#[worker(name = "greet")]
async fn greet(name: String) -> String {
format!("Hello {}", name)
}
Step 3: Run your first workflow app
Create a main.rs with the following:
use conductor::{
client::ConductorClient,
configuration::Configuration,
models::{StartWorkflowRequest, WorkflowDef, WorkflowTask},
worker::TaskHandler,
};
use conductor_macros::worker;
// A worker is any Rust function with the #[worker] macro.
#[worker(name = "greet")]
async fn greet(name: String) -> String {
format!("Hello {}", name)
}
fn greetings_workflow() -> WorkflowDef {
WorkflowDef::new("greetings")
.with_version(1)
.with_task(
WorkflowTask::simple("greet", "greet_ref")
.with_input_param("name", "${workflow.input.name}")
)
.with_output_param("result", "${greet_ref.output.result}")
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Configure the SDK (reads CONDUCTOR_SERVER_URL / CONDUCTOR_AUTH_* from env).
let config = Configuration::default();
let client = ConductorClient::new(config.clone())?;
// Register the workflow
let workflow = greetings_workflow();
client.metadata_client()
.register_or_update_workflow_def(&workflow, true)
.await?;
// Start polling for tasks
let mut task_handler = TaskHandler::new(config.clone())?;
task_handler.add_worker(greet_worker());
task_handler.start().await?;
// Run the workflow and get the result
let run = client.workflow_client()
.execute_workflow(
&StartWorkflowRequest::new("greetings")
.with_version(1)
.with_input_value("name", "Conductor"),
std::time::Duration::from_secs(10),
)
.await?;
println!("result: {:?}", run.output.get("result"));
println!("execution: {}/execution/{}", config.ui_host, run.workflow_id);
task_handler.stop().await?;
Ok(())
}
Run it:
See the rust-sdk README for details.
That's it -- you just defined a worker, built a workflow, and executed it. Open the UI for the Conductor server you configured to inspect the execution.
Comprehensive worker example
The example includes sync + async workers, metrics, and long-running tasks.
See examples/worker_example.rs
Workers
Workers are Rust functions that execute Conductor tasks. Use the #[worker] macro or FnWorker to:
- register it as a worker (auto-discovered by
TaskHandler) - use it as a workflow task (call it with
task_ref_name=...)
Note: Workers can also be used by LLMs for tool calling (see AI & LLM Workflows).
use conductor_macros::worker;
#[worker(name = "greet")]
async fn greet(name: String) -> String {
format!("Hello {}", name)
}
Using FnWorker (closure-based):
use conductor::worker::{FnWorker, WorkerOutput};
let greetings_worker = FnWorker::new("greetings", |task| async move {
let name = task.get_input_string("name").unwrap_or_default();
Ok(WorkerOutput::completed_with_result(format!("Hello, {}", name)))
})
.with_thread_count(10)
.with_poll_interval_millis(100);
Start workers with TaskHandler:
use conductor::{
configuration::Configuration,
worker::TaskHandler,
};
let config = Configuration::default();
let mut task_handler = TaskHandler::new(config)?;
task_handler.add_worker(greet_worker());
task_handler.start().await?;
// Wait for shutdown signal
tokio::signal::ctrl_c().await?;
task_handler.stop().await?;
Worker Configuration
Workers support hierarchical environment variable configuration — global settings that can be overridden per worker:
# Global (all workers)
export CONDUCTOR_WORKER_ALL_POLL_INTERVAL_MILLIS=250
export CONDUCTOR_WORKER_ALL_THREAD_COUNT=20
export CONDUCTOR_WORKER_ALL_DOMAIN=production
# Per-worker override
export CONDUCTOR_WORKER_GREETINGS_THREAD_COUNT=50
See WORKER_CONFIGURATION.md for all options.
Monitoring Workers
Enable Prometheus metrics:
use conductor::metrics::MetricsSettings;
use conductor::worker::TaskHandler;
let mut task_handler = TaskHandler::new(config)?;
task_handler.enable_metrics(
MetricsSettings::new()
.with_http_port(9090)
);
task_handler.start().await?;
// Metrics at http://localhost:9090/metrics
See the rust-sdk README for details.
Learn more: - Worker Guide — All worker patterns (function, closure, macro, async) - Worker Configuration — Environment variable configuration system
Workflows
Define workflows in Rust using the builder pattern to chain tasks:
use conductor::{
client::ConductorClient,
configuration::Configuration,
models::{WorkflowDef, WorkflowTask},
};
let config = Configuration::default();
let client = ConductorClient::new(config)?;
let metadata_client = client.metadata_client();
let workflow = WorkflowDef::new("greetings")
.with_version(1)
.with_task(
WorkflowTask::simple("greet", "greet_ref")
.with_input_param("name", "${workflow.input.name}")
)
.with_output_param("result", "${greet_ref.output.result}");
// Registering is required if you want to start/execute by name+version
metadata_client.register_or_update_workflow_def(&workflow, true).await?;
Execute workflows:
use conductor::models::StartWorkflowRequest;
use std::time::Duration;
// Asynchronous (returns workflow ID immediately)
let request = StartWorkflowRequest::new("greetings")
.with_version(1)
.with_input_value("name", "Orkes");
let workflow_id = workflow_client.start_workflow(&request).await?;
// Synchronous (waits for completion)
let run = workflow_client
.execute_workflow(&request, Duration::from_secs(10))
.await?;
println!("{:?}", run.output);
Manage running workflows and send signals:
workflow_client.pause_workflow(&workflow_id).await?;
workflow_client.resume_workflow(&workflow_id).await?;
workflow_client.terminate_workflow(&workflow_id, Some("no longer needed"), false).await?;
workflow_client.retry_workflow(&workflow_id, false).await?;
workflow_client.restart_workflow(&workflow_id, false).await?;
Learn more: - Workflow Management — Start, pause, resume, terminate, retry, search - Metadata Management — Task & workflow definitions
Troubleshooting
- Worker stops polling:
TaskHandlermonitors workers. Usetask_handler.is_healthy()for health checks. - Connection issues: Verify
CONDUCTOR_SERVER_URLis correct and server is running. - Authentication failures: For Orkes Conductor, ensure
CONDUCTOR_AUTH_KEYandCONDUCTOR_AUTH_SECRETare valid.
AI & LLM Workflows
Conductor supports AI-native workflows including agentic tool calling, RAG pipelines, and multi-agent orchestration.
Agentic Workflows
Build AI agents where LLMs dynamically select and call Rust workers as tools. See examples/ for all examples.
| Example | Description |
|---|---|
| llm_chat_example.rs | Automated multi-turn science Q&A between two LLMs |
| llm_chat_human_in_loop.rs | Interactive chat with WAIT task pauses for user input |
| multiagent_chat.rs | Multi-agent discussion with expert, critic, and synthesizer |
| function_calling_example.rs | LLM picks which function to call based on user queries |
| agentic_workflow.rs | AI agent with tool calling and switch-based routing |
LLM and RAG Workflows
| Example | Description |
|---|---|
| rag_workflow.rs | End-to-end RAG: text indexing, semantic search, answer generation |
| vector_db_example.rs | Vector database operations with embedding generation |
# Automated multi-turn chat
cargo run --example llm_chat_example
# Multi-agent discussion
cargo run --example multiagent_chat
# RAG pipeline
cargo run --example rag_workflow
Examples
See the examples directory for the full catalog. Key examples:
| Example | Description | Run |
|---|---|---|
| worker_example.rs | End-to-end: sync + async workers, metrics | cargo run --example worker_example |
| hello_world.rs | Minimal hello world | cargo run --example hello_world |
| dynamic_workflow.rs | Build workflows programmatically | cargo run --example dynamic_workflow |
| llm_chat_example.rs | AI multi-turn chat | cargo run --example llm_chat_example |
| rag_workflow.rs | RAG pipeline | cargo run --example rag_workflow |
| task_context_example.rs | Long-running tasks with TaskContext | cargo run --example task_context_example |
| workflow_ops.rs | Pause, resume, terminate workflows | cargo run --example workflow_ops |
| test_workflows.rs | Unit testing workflows | cargo run --example test_workflows |
| kitchensink.rs | All task types (HTTP, JS, JQ, Switch) | cargo run --example kitchensink |
API Journey Examples
End-to-end examples covering all APIs for each domain:
| Example | APIs | Run |
|---|---|---|
| authorization_example.rs | Authorization APIs | cargo run --example authorization_example |
| metadata_journey.rs | Metadata APIs | cargo run --example metadata_journey |
| schedule_journey.rs | Schedule APIs | cargo run --example schedule_journey |
| prompt_journey.rs | Prompt APIs | cargo run --example prompt_journey |
Documentation
| Document | Description |
|---|---|
| Worker Guide | All worker patterns (function, closure, macro, async) |
| Worker Configuration | Hierarchical environment variable configuration |
| Workflow Management | Start, pause, resume, terminate, retry, search |
| Task Management | Task operations |
| Metadata | Task & workflow definitions |
| Authorization | Users, groups, applications, permissions |
| Schedules | Workflow scheduling |
| Secrets | Secret storage |
| Prompts | AI/LLM prompt templates |
| Integrations | AI/LLM provider integrations |
| Metrics | Prometheus metrics collection |
Support
- Open an issue (SDK) for SDK bugs, questions, and feature requests
- Open an issue (Conductor server) for Conductor OSS server issues
- Join the Conductor Slack for community discussion and help
- Orkes Community Forum for Q&A
License
Apache 2.0