Counting visitors…
Browse all docs
Start · 9Find your path through RunifoldLearn Runifold in 45 minutesUnderstand the complete Runifold platformYour first trustworthy runChoose the right execution APIChoose crates and Cargo featuresBuild common Runifold applicationsRunifold frequently asked questionsTroubleshoot Runifold applications
Execution kernel · 7Understand RunContextCoordinate external effects safelyBound work with budgets and cancellationHandle errors and retries safelyEvents, journals, and execution evidenceDesign capability-safe executionRecover safely from checkpoints
Models & providers · 7Route across models without duplicate outputChoose and configure a providerUse the provider-neutral model protocolBuild on the Provider Runtime contractUse OpenAI control-plane and Realtime APIsTest and benchmark provider adaptersSet up OpenAI, Anthropic, Gemini, and Ollama
Agents · 7Build and configure an AgentGive an Agent typed toolsAdd conversations and semantic memoryDelegate to child Agents safelyReturn structured Rust valuesStream without losing semanticsGround an Agent with retrieval
Durable workflows · 7Compose deterministic workflowsMake workflows durableOperate durable workflow workersCoordinate timers, signals, and durable waitsRun multi-tenant workflow infrastructureRun parallel branches and safe racesVersion and evolve durable workflows
Integrations · 7Connect through MCPChoose stores and persistence boundariesExpose durable work through MCP TasksBuild and evaluate retrieval pipelinesUse MCP Resources, Prompts, and SamplingCache MCP responses without crossing authorityDeploy Runifold in a Rust web service
Quality & operations · 10Test without the networkEvaluate quality and prevent regressionsObserve the complete run treeRun safely in browsers and at the edgeRead reliability claims preciselyRun reproducible evaluations in CIOperate Runifold with SLOsGovern Task retention and deletionArchive audit evidence to S3-compatible WORM storageManage compatibility and trusted releases
Docs/Core course
Core course

Learn Runifold in 45 minutes

Build the right mental model, complete a real run, add a typed contract, bound execution, and choose what to learn next.

Practical guide·10 min
YOUR 45-MINUTE CORE

Five checkpoints. One working mental model.

0% complete
  1. Explain the execution pathProvider → Runtime → Agent → Run → Outcome5 min
  2. Complete the first runInstall Runifold and receive one model response10 min
  3. Create a typed contractTurn model output into a Rust value10 min
  4. Bound the executionAdd budgets, a deadline, and explicit authority10 min
  5. Choose the next architectureOpen only the guides your product needs10 min

This course uses one Agent as a compact vertical slice through the kernel and model layers. Runifold can also be used directly as a model protocol, durable Workflow runtime, MCP edge, evaluation system, or observability layer. See the complete platform map for those entry points.

Build the mental model

Runifold is easiest to learn as one execution path:

ProviderRuntimeAgentRunOutcome
  • Provider translates one model service's wire protocol.
  • Runtime adds routing and safe transport behavior around a model identity.
  • Agent combines instructions, callable tools, and turn policy.
  • Run carries identity, lifetime, budget, authority, and journal events.
  • Outcome preserves visible text together with usage and execution facts.

The one sentence worth remembering is: the model proposes work; the Run defines what may happen and how it is accounted for.

Checkpoint: without looking above, explain where authentication, tools, budgets, and final text belong. If the four answers are Provider, Agent, Run, and Outcome, continue.

Complete the first run

Create a project, add the stable runtime, and select the provider adapter you use:

cargo new hello-runifold
cd hello-runifold
cargo add runifold@0.9.0
cargo add runifold-providers@0.9.0 --features openai
cargo add tokio --features macros,rt-multi-thread
export OPENAI_API_KEY="your-api-key"

Replace src/main.rs with this complete program:

use runifold::ProviderModelExt;
use runifold_providers::openai::OpenAiClient;
 
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let runtime = OpenAiClient::from_api_key(
        std::env::var("OPENAI_API_KEY")?
    )?
    .runtime("gpt-5")?;
 
    let answer = runtime
        .agent("assistant")
        .system("Answer precisely and expose uncertainty.")
        .prompt_text("Explain one benefit of durable execution.")
        .await?;
 
    println!("{answer}");
    Ok(())
}

Run cargo run. Success means the process exits normally and prints one answer. The exact wording is not a test because model output is nondeterministic.

Read the code from the outside in: the client authenticates, runtime chooses the model edge, agent defines behavior, and prompt_text creates a convenient root Run.

Create a typed contract

Text is useful at a user interface. Application logic should normally receive a Rust value. Add:

cargo add serde --features derive
cargo add schemars

Define the contract, then build a structured Agent:

use runifold::JsonSchema;
use serde::Deserialize;
 
#[derive(Debug, Deserialize, JsonSchema)]
struct Triage {
    category: String,
    urgent: bool,
    explanation: String,
}
 
let agent = runtime
    .agent("triage")
    .system("Classify the request. Keep the explanation short.")
    .build_structured::<Triage>("triage_result")?;
 
let run = agent.agent().default_run_context();
let result = agent.run("Payment failed twice", &run).await?;
println!("{:?}", result.output);

The schema constrains the model-facing format; deserialization establishes the Rust boundary. Domain validation still belongs in ordinary Rust after decoding. Never silently fall back to unvalidated text when the contract fails.

Checkpoint: change urgent to a string temporarily. Your surrounding application code should expose the contract mismatch instead of guessing.

Bound the execution

The default context is ideal for exploration. At an HTTP request, background job, or workflow boundary, replace it with an explicit RunContext:

use std::time::{Duration, Instant};
use runifold::{Budget, BudgetTracker, CapabilitySet, RunContext};
 
let run = RunContext::root(
    BudgetTracker::new(Budget {
        tokens: Some(20_000),
        turns: Some(8),
        tool_calls: Some(4),
        ..Budget::default()
    }),
    CapabilitySet::new(),
)
.with_deadline(Instant::now() + Duration::from_secs(20));

This creates one shared envelope for descendants. Child Agents and tools spend from the same accounting tree, observe cancellation, and receive only explicitly granted capabilities.

Three distinctions prevent most design mistakes:

Do not confuseCorrect boundary
chat history with execution statetranscripts are model context; RunContext is control state
registered tools with permissionregistration says what exists; capabilities say what this Run may use
network timeout with deadlinetimeout bounds one operation; deadline bounds the useful lifetime of the run tree

Pass the ship checkpoint

You now know the stable core. Choose only the branch your product needs:

Product requirementRead nextYou can postpone
user-facing chatConversations and memoryworkflows
calls application functionsTyped tools, then effects for writesdelegation
coordinates specialistsDelegationdurable workflows
survives restarts or long waitsWorkflows, then durable workflowsstreaming
must meet a quality barTesting, then evaluationadditional providers
needs production evidenceObservability, reliabilityedge and WASM

Before shipping a feature, answer these six questions:

  1. What is the root Run boundary?
  2. Which model and provider behavior has been verified?
  3. Which capabilities can this Run use?
  4. What bounds tokens, turns, tool calls, and wall time?
  5. Which external writes are idempotent or recoverable?
  6. How will a failed Run be explained and reproduced?

If any answer is “the prompt handles it,” move that responsibility into typed Rust policy before production.