Build common Runifold applications
Choose a task-oriented recipe for text, structured output, Tools, streaming, memory, retrieval, workflows, and MCP.
Choose a recipe
Start from the product behavior you need. Every recipe below uses the same execution model, so moving from a prototype to a bounded Run does not require a framework rewrite.
| I want to… | Start here | Add before production |
|---|---|---|
| ask a model one question | first run | explicit model, timeout, error policy |
| return a Rust value | structured output | domain validation and refusal handling |
| call application code | typed tools | capabilities, budgets, and effect policy |
| stream to a UI | streaming | disconnect cancellation and terminal-state handling |
| preserve a conversation | conversations | context window and tenant namespace |
| answer from documents | retrieval | attribution, tenant filtering, and evaluation |
| coordinate fixed steps | workflows | checkpoints and recovery policy |
| expose remote capabilities | MCP | authorization partitions and transport limits |
One-shot and typed output
Use prompt_text at text boundaries. Use a structured Agent when application
logic needs a contract:
use runifold::JsonSchema;
use serde::Deserialize;
#[derive(Debug, Deserialize, JsonSchema)]
struct Triage {
category: String,
urgent: bool,
explanation: String,
}
let structured = runtime
.agent("triage")
.system("Classify the request. Keep the explanation short.")
.build_structured::<Triage>("triage_result")?;
let run = structured.agent().default_run_context();
let result = structured.run("Payment failed twice", &run).await?;
println!("{:?}", result.output);Schema acceptance is not domain validation. Validate business invariants after deserialization and fail closed if the model refuses or returns invalid output.
Tools, streaming, and memory
These features solve different problems:
- a Tool lets a model propose a call to typed Rust code;
- a stream exposes ordered model, Tool, usage, warning, and terminal events;
- conversation storage persists messages and versions across requests;
- a RunContext carries authority, budgets, cancellation, deadlines, and journal state for one execution tree.
Do not use chat history as execution state or Tool registration as authorization. Follow typed tools, streaming, and conversations independently, then compose them.
Workflows and long-running work
Use ordinary Agent execution when the model decides the next turn. Use a Workflow when your application owns the sequence, branch, join, timer, signal, or recovery boundary.
For a durable job:
- define stable step identifiers and a workflow version;
- give every step an explicit capability set;
- persist checkpoints and external effects before execution;
- run Workers with fenced leases and heartbeats;
- define how unknown or ambiguous states are recovered.
Read workflows, durability, and Workers in that order.
Know what is verified
The Quickstart, structured output, Tool, streaming, conversation, delegation,
routing, and web-service examples are compiled in documentation CI against the
exact public runifold = 0.9.0 release. A successful compile proves the API
surface matches the page; live provider behavior still requires credentials and
a model-specific smoke test.
Use the testing guide for deterministic behavior and Provider testing for real protocol evidence.