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/Models and providers
NEW TO RUNIFOLD?Build the complete mental model in 45 minutes
Models and providers

Use the provider-neutral model protocol

Understand requests, ordered content, capability negotiation, canonical streaming, responses, usage, and provider extensions.

Practical guide·12 min

The Model boundary

runifold-model is usable without an Agent. Its object-safe Model contract opens a canonical event stream and can collect that stream into the same ModelResponse used by non-streaming callers. ModelCallContext carries only invocation identity, optional owning Run identity, deadline, and cancellation.

Credentials, endpoints, HTTP clients, retries, and routing remain adapter or middleware configuration. This keeps the invocation protocol composable and testable.

Lossless content

Messages contain ordered content parts rather than one flattened string. Normalized variants preserve text, media, reasoning, tool calls, tool results, refusals, citations, and usage. Unknown provider data uses namespaced extensions instead of being silently discarded.

Visible answer text and reasoning remain distinct. Application code that needs the whole response should inspect ModelResponse; concatenating text deltas throws away the evidence required for tools, cost, diagnostics, and safety.

Capability negotiation

ModelCapabilities describes feature support as native, emulated, unsupported, or unknown. A request policy can require strict support, allow emulation, or accept best effort. Degradation must appear as warnings.

Treat capability discovery as evidence for one provider/model combination, not a universal promise. Test structured output, reasoning, tool calling, embeddings, media, and usage details on the exact route you deploy.

Canonical streaming

A valid stream starts once, opens and completes indexed content blocks, may emit usage snapshots or provider events, and completes exactly once. Ending without a terminal event, completing with an open block, or emitting after completion is a protocol error.

Retry or fallback may happen only before the first canonical event commits the stream. After visible output begins, switching routes could duplicate content or mix two provider responses.

Direct model calls

Use the model layer directly when you need request/response control but not an Agent loop: proxying a model, benchmarking adapters, running batch transformations, implementing custom orchestration, or testing provider semantics.

Use an Agent when the model must repeatedly choose Tools or child Agents. Use a Workflow when application code owns deterministic transitions. These layers compose; none is a mandatory wrapper around the others.

Invoke the low-level Model API

use runifold::{
    Message, Model, ModelCallContext, ModelRef, ModelRequest,
};
use runifold_providers::openai::OpenAiClient;
 
let client = OpenAiClient::from_api_key(std::env::var("OPENAI_API_KEY")?)?;
let request = ModelRequest::new(
    ModelRef::new("openai", "gpt-5"),
    Message::user("Explain lease fencing in one paragraph"),
);
let response = client.invoke(request, ModelCallContext::new()).await?;
 
for part in response.content {
    if let Some(text) = part.as_text() {
        println!("{text}");
    }
}

Use this surface when building an adapter or when you explicitly do not need the Agent loop. Inspect canonical content, finish reason, usage, warnings, and provider extensions; do not parse a provider's raw JSON in application code. Add cancellation and deadline to ModelCallContext before production.