swiftide
Library Listed
Composable LLM agents, typed task graphs, and streaming RAG pipelines in Rust
- Downloads
- 1,100
- Dependents
- 7
- Stars
- 803
- Forks
- 74
- Contributors
- 28
- Commits
- 920
- Latest release
- 0.34.0 ·
About
Composable LLM agents and harness, typed task graphs, and streaming RAG pipelines in Rust.
API docs
·
Examples
·
Website
·
Discord
Swiftide is an opinionated framework for building LLM applications. It gives you an agent harness, typed task graphs for orchestration, and streaming, composable indexing/query pipelines for RAG.
Table of Contents
- Why Swiftide
- Quick Start
- Agent Harness
- Agent Tools and Hooks
- Typed Task Graphs
- RAG Pipelines
- Integrations
- Examples
- Project Status
- Contributing
- Core Team Members
- License
Why Swiftide
- Build agents that loop over LLM calls, tool calls, lifecycle hooks, and stop conditions.
- Compose prompt steps, agents, command executors, and domain-specific Rust code in typed task graphs.
- Fan out work into parallel branches and join typed results back into one task output.
- Pause and resume agents or tasks for human approval, external callbacks, or persisted state.
- Bring tools from local Rust functions, custom
Toolimplementations, or MCP servers. - Stream large indexing and retrieval workloads through loaders, transformers, embedders, caches, and storage backends.
- Trace agent, task, and pipeline execution with
tracing, metrics, and Langfuse support.
Read the full README
The core primitives provide the shared interaction model. Around them, use pipelines for data flows, agents for tool loops, and tasks for graphs of typed hand-offs.
Quick Start
Swiftide keeps default dependencies light. Start with the agent harness and add the integrations your application needs.
cargo add swiftide --features swiftide-agents,openai
cargo add anyhow
cargo add tokio --features macros,rt-multi-thread
HTTPS works out of the box: Swiftide's HTTP clients use rustls with a built-in crypto provider.
If your application installs its own process-wide rustls CryptoProvider before creating
clients, Swiftide uses that one instead. Redis over rediss:// needs a process-wide provider; if
none is installed when it connects, Swiftide installs aws-lc-rs.
If using OpenAI, set the API key expected by the OpenAI-compatible integration:
export OPENAI_API_KEY=...
To use another OpenAI-compatible endpoint, such as a gateway, vLLM or LiteLLM, set its URL and key on the builder:
let openai = OpenAI::builder()
.api_base("http://127.0.0.1:8080/v1")
.api_key("...")
.default_prompt_model("my-model")
.build()?;
Agent Harness
Use the agent harness to call a model, run tools, and control when an agent stops. Add tools as
Rust functions or Tool implementations, and use hooks to run logic during the agent lifecycle.
AgentContext manages conversation history and gives tools access to a ToolExecutor. Use the
local executor or run commands in an isolated environment with the
Docker executor.
use anyhow::Result;
use swiftide::{
agents,
chat_completion::{ToolOutput, errors::ToolError},
traits::AgentContext,
};
#[swiftide::tool(
description = "Looks up a Swiftide concept",
param(name = "concept", description = "Concept to explain")
)]
async fn explain_concept(
_context: &dyn AgentContext,
concept: &str,
) -> Result<ToolOutput, ToolError> {
let explanation = match concept {
"tasks" => "Tasks compose typed nodes into explicit workflows.",
"agents" => "Agents run LLM completions, tools, hooks, and stop conditions.",
"pipelines" => "Pipelines stream data through indexing and retrieval steps.",
_ => "Swiftide composes agents, task graphs, tools, and RAG pipelines.",
};
Ok(explanation.into())
}
#[tokio::main]
async fn main() -> Result<()> {
let openai = swiftide::integrations::openai::OpenAI::builder()
.default_prompt_model("gpt-4o-mini")
.build()?;
agents::Agent::builder()
.llm(&openai)
.tools([explain_concept()])
.on_new_message(|_, message| {
println!("{message}");
Box::pin(async { Ok(()) })
})
.limit(8)
.build()?
.query("Explain Swiftide tasks and agents in one paragraph.")
.await?;
Ok(())
}
The agent calls the model, exposes explain_concept as a tool, prints new messages, and stops
within the configured turn limit. By default all agents have a tool to stop the loop. This can be customized.
Agent capabilities include:
- function tools through
#[swiftide::tool], derived tools, or manualToolimplementations - lifecycle hooks before and after completions, tools, messages, streaming chunks, start, and stop
- local or custom
ToolExecutorimplementations for command/file access - human-in-the-loop approval via
ApprovalRequiredand feedback-aware contexts - structured stop and failure payloads with custom JSON schemas
- MCP toolboxes that load tools at runtime
- streaming responses and reasoning-item handling for providers that support them
Start with examples/hello_agents.rs,
then look at the human approval, MCP, streaming, resume, and structured-output examples.
Agent Tools and Hooks
Use swiftide-agents-contrib to add file tools, plans,
context hooks, and lazy executors to your agents. Choose the features you need and register
the components on your agent.
Feature on swiftide | What it provides |
|---|---|
agents-contrib-file-tools | Read file pages or selected lines with ReadFile, replace text with ExactReplace, and edit files with ApplyPatch. |
agents-contrib-planning | Track steps and progress with UpdatePlan. |
agents-contrib-context | Shorten large tool outputs with ToolSummarizer and summarize long conversations with ContextCompression. |
agents-contrib-lazy-executor | Start an executor when the agent first needs it with LazyExecutor. |
cargo add swiftide --features agents-contrib-file-tools,agents-contrib-planning
Import components from swiftide::agents_contrib, for example
swiftide::agents_contrib::tools::ReadFile registers read_file; add .with_line_numbers()
for read_file_with_line_numbers. Both accept file_name, optional one-based offset, and optional
limit. Reads default to 2,000 lines, truncate long lines at 2,000 characters, and refuse windows
above the 100,000-character budget. Partial pages explain how to continue.
Contrib features are off by default. See the crate guide
for examples, defaults, and the features to use when depending on the contrib crate directly.
Typed Task Graphs
Tasks are Swiftide's orchestration layer. A task is a typed graph of TaskNode steps. Each node has
an input type, output type, and error type; transitions decide where the output goes next.
Tasks are strongly typed at build time. It allows you to compose agents, other swiftide components, and functions to create complex automations.
From examples/tasks.rs.
use swiftide::{
prompt::Prompt,
tasks::{Task, TaskRunOutcome, Transition},
traits::SimplePrompt,
};
use std::sync::Arc;
let prompt_model: Arc<dyn SimplePrompt> = Arc::new(openai.clone());
let briefing_agent = BriefingAgent::new(agent);
let mut task: Task<Prompt, String> = Task::new();
let brief = task.register_node(prompt_model.clone());
let decide = task.register_node(briefing_agent);
let render = task.register_node(prompt_model);
task.starts_with(brief);
task.register_transition(brief, move |short_brief| {
decide.transitions_with(short_brief)
})?;
task.register_transition(decide, move |decision: BriefingDecision| {
Transition::next(
&render,
Prompt::from("Write a hand-off note for {{audience}}: {{summary}}")
.with_context_value("audience", decision.audience)
.with_context_value("summary", decision.summary),
)
})?;
task.register_transition(render, task.transitions_to_finish())?;
match task.run(Prompt::from("Summarize the rollout plan")).await? {
TaskRunOutcome::Completed(note) => println!("{note}"),
TaskRunOutcome::Paused => println!("Task paused"),
}
Task capabilities include:
- closure nodes for small glue steps and
TaskNodeimplementations for domain logic - typed
NodeIdhandles, transitions, and join payloads - static fan-out with explicit joins
- sequential or parallel branch execution
- pause, resume, and reset support
- adapters for prompt-like Swiftide primitives, chat completions, and tool executors
TaskAgentfor the simple case where an agent should run as a task node
See examples/tasks.rs for a
prompt plus custom agent workflow, and
examples/tasks_fanout.rs
for fan-out and join.
RAG Pipelines
Swiftide includes first-class indexing and querying pipelines for retrieval-augmented generation. Pipelines are streaming and composable: load data, transform it, embed it, cache it, store it, then retrieve and answer with a typed query flow.
use swiftide::{
indexing::{self, loaders::FileLoader, transformers::{ChunkCode, Embed, MetadataQACode}},
integrations::qdrant::Qdrant,
};
async fn index(openai: swiftide::integrations::openai::OpenAI) -> anyhow::Result<()> {
let qdrant = Qdrant::builder()
.collection_name("swiftide-code")
.vector_size(1536)
.batch_size(50)
.build()?;
indexing::Pipeline::from_loader(FileLoader::new(".").with_extensions(&["rs"]))
.with_default_llm_client(openai.clone())
.then_chunk(ChunkCode::try_for_language_and_chunk_size("rust", 10..2048)?)
.then(MetadataQACode::default())
.then_in_batch(Embed::new(openai))
.then_store_with(qdrant)
.run()
.await?;
Ok(())
}
Indexing supports loaders, caches, chunkers, transformers, batch transformers, embedders, and storage backends. Query pipelines support query transformation, retrieval, response transformation, answer generation, hybrid search, reranking patterns, and evaluation.
Integrations
Swiftide integrations are feature-gated so application builds stay intentional.
| Area | Supported integrations |
|---|---|
| LLM providers | OpenAI and Azure OpenAI, Anthropic, Gemini, OpenRouter, AWS Bedrock Converse API, Groq, Ollama, Dashscope |
| Tooling | MCP toolboxes, local command execution, custom tool executors |
| Storage and retrieval | Qdrant, Redis, LanceDB, PgVector, DuckDB, Redb |
| Loading data | Files, scraping, Fluvio, Kafka, Parquet, executor-backed file streams |
| Code and text processing | Markdown, text splitting, tree-sitter code chunking and metadata |
| Observability | tracing, metrics, Langfuse |
Examples
The examples has a variety of examples.
- Agents:
hello_agents.rs,streaming_agents.rs,agents_with_human_in_the_loop.rs,agents_mcp_tools.rs - Structured outputs and control tools:
stop_with_args_custom_schema.rs,agent_can_fail_custom_schema.rs - Tasks:
tasks.rs,tasks_fanout.rs - RAG and retrieval:
index_codebase.rs,query_pipeline.rs,hybrid_search.rs - Provider and observability examples:
responses_api.rs,responses_api_reasoning.rs,aws_bedrock_agent.rs,langfuse.rs
More background is available on the Bosun blog, including posts about tasks, streaming agents, human-in-the-loop flows, and Rust performance for AI tools.
Project Status
Swiftide is pre-1.0. APIs can change while the agent harness and task graph APIs settle around production use. The current API docs and examples are the most reliable source of exact signatures.
Swiftide is part of the bosun.ai project.
Contributing
Contributions are welcome. Read CONTRIBUTING.md, open an issue for design discussion, file a bug report, or propose a feature. Join the Discord for a faster feedback loop.
Before opening a pull request:
- Run the focused checks for the crates you changed.
- Run
cargo +nightly fmt --all -- --check. - Run
cargo clippy --workspace --all-targets --all-features -- -D warningswhen touching shared behavior. - Add or update examples, tests, or rustdoc when behavior changes.
AI-generated code is welcome and should be reviewed like any other code. Keep abstractions small, keep domain logic separate from plumbing, and pay attention to allocations in indexing, querying, and task execution paths.
AI agents can refer to AGENTS.md for workspace layout, commands, and expectations.
Core Team Members
License
Distributed under the MIT License. See LICENSE for more information.
(back to top)
Compatibility
- Runs on
- GPU support unknown
What shows it
- no dependency or feature matches a backend row
- Native code
- Optional
- Binds native code: tree-sitter (feature tree-sitter), libduckdb-sys (feature duckdb), rdkafka-sys (feature kafka), tree-sitter-language (feature tree-sitter)
- Python bindings
- No Python binding crate found
- License
- MIT
Compare with similar projects
Order: strongest tier first, then most downloads, then name, with unmeasured values last. A library counts downloads over 30 days. An app counts binary downloads per release. An app with none counts its crate downloads over 30 days. ML Rust runs this catalogue, so its closest project always gets a row.
| Project | Downloads | Dependents | Stars | Latest release | Runs on (GPU) | Native code | License |
|---|---|---|---|---|---|---|---|
|
Composable LLM agents, typed task graphs, and streaming RAG pipelines in Rust |
1,100 downloads over 30 days | 7 | 803 | 0.34.0 | GPU support unknown | Binds native code: tree-sitter (feature tree-sitter), libduckdb-sys (feature duckdb), rdkafka-sys (feature kafka), tree-sitter-language (feature tree-sitter) | MIT |
|
adk-rust Listed
Rust Agent Development Kit - Build AI agents in Rust with modular components for models, tools, memory, and more. |
5,419 downloads over 30 days | 25 | 743 | 2.3.0 | CUDA, Metal | Binds native code: alsa-sys (feature desktop-audio), audiopus_sys (feature openai-webrtc), cxx (feature livekit), espeak-rs-sys (feature kokoro), libsqlite3-sys (feature sqlite) and 4 more | Apache-2.0 |
|
chidori Listed
The agent framework where every run is durable, replayable, and resumable by default. Plain async TypeScript agents on an embedded pure-Rust JS engine. Python bindings |
257 downloads over 30 days | 0 | 1,372 | 3.8.1 | GPU support unknown | Binds native code: aws-lc-rs, aws-lc-sys, lcms2-sys, libffi-sys, libsqlite3-sys and 4 more | Apache-2.0 |
|
tokio-prompt-orchestrator Listed
Put a queue, deduplication and a circuit breaker in front of any LLM API, so repeated prompts cost one call and outages fail fast. Rust library, HTTP server and CLI. |
68 downloads over 30 days | 0 | 60 | 2.0.5 | GPU support unknown | No native code found | MIT |
|
Rust-native, library-first coding-agent runtime and terminal CLI inspired by Pi, with composable LLM providers, tools, sessions, and plugin ABI |
16 binary downloads per release | Not applicable | 231 | Not measured | Not measured | MIT | |
|
An open protocol that gives AI agents a secure, sandboxed place to run code and use tools — with lean context usage. AXP works alongside MCP |
Not measured | Not applicable | 3 | Not measured | Not measured | Not measured | Apache-2.0 |
|
Experimenting with LLMs through Ollama and retrieval augmented generation (RAG) in Rust |
Not measured | Not applicable | 19 | Not measured | Not measured | Not measured | Apache-2.0 |
Why ListedNo archive, New or Featured rule places it, so it is Listed.
What it lacks for Featured
- It has 1 active dependents and 1 new dependents in 365 days. Featured needs 11 active dependents or 9 new dependents in 365 days. The repository route reads 803 stars, 74 forks and 28 contributors. It needs 4,539 stars, 434 forks and 79 contributors together.
What else the check found
- The last activity is on 6 Nov 2026, 3 days ago. The rules expect an update within 365 days. Dormancy rule
Exact rules: Listed, Featured library. The check on applied thresholds version 9.
Every rule outcome, as the check records it
expected-interval: version 0.34.0 base 140, raised to the 365-day floor: E = 365 daysdormancy: last activity 2026-11-06, 3 days ago, E = 365: activefeatured: not featured: active_users 1 < 11 and new_adopters 1 < 9 and repository route stars 803 (needs 4539), forks 74 (needs 434), contributors 28 (needs 79)listed: listed: no archive, new or featured rule applies
Crates9 crates
Measurements and sources
Each signal row shows the raw value, its source and the fetch date. The Sources list gathers every distinct source on this page. Movement needs more history.
Sources6 sources
- Description: the crates.io description
- crates.io database dump, fetched
- RustSec advisory database, fetched
- GitHub repository, fetched
- crates.io package, fetched
- GitHub contributors, fetched
Adoption1 active dependents, 1 new dependents in 365 days1 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Active dependents | 1 | crates.io database dump | Yes | |
| New dependents (365 days) | 1 | crates.io database dump | Yes | |
| Peak active dependents | 1 | crates.io database dump | Yes | |
| Active dependents as a share of the peak | 1 | crates.io database dump | Yes | |
| Binary downloads per release | Not measured | Yes |
MaintenanceLatest human commit: 3 days ago3 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Latest human commit | 2026-11-06 | GitHub repository | Yes | |
| Latest release | 2026-11-06 | crates.io database dump | Yes | |
| First release | 2024-06-13 | crates.io database dump | Yes | |
| Latest version | 0.34.0 | crates.io database dump | Yes | |
| Days the oldest outside issue waits for a reply | 200 | GitHub repository | Yes | |
| Maintainer replies over 365 days | 21 | GitHub repository | Yes | |
| Repository archived | false | GitHub repository | Yes | |
| Repository gone | false | GitHub repository | Yes | |
| Release commit or manifest in the repo | true | crates.io package | Yes | |
| Published docs | true | crates.io database dump | Yes | |
| Latest release fails cargo check | Not measured | Yes | ||
| Build check date | Not measured | Yes | ||
| Build check toolchain | Not measured | Yes |
SecurityUnpatched vulnerabilities: none
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Unpatched vulnerabilities past the grace window | none | RustSec advisory database | Yes | |
| RustSec unmaintained advisory | none | RustSec advisory database | Yes | |
| Deprecation notice | none | crates.io database dump | Yes | |
| Deprecated requirement | none | crates.io database dump | Yes |
Distribution93 releases, 1,100 downloads over 30 days5 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Releases | 93 | crates.io database dump | Yes | |
| Downloads over 30 days | 1100 | crates.io database dump | Yes | |
| Binary downloads over the last 3 releases | Not measured | Yes | ||
| Homebrew installs on request over 365 days | Not measured | Yes | ||
| Repology repository families | Not measured | Yes | ||
| Docker pull growth over 90 days | Not measured | Yes | ||
| Docker pulls at the growth baseline | Not measured | Yes | ||
| Every version a prerelease | false | crates.io database dump | Yes | |
| Every version 0.0.x | false | crates.io database dump | Yes | |
| Every version yanked | false | crates.io database dump | Yes | |
| Crate deleted from crates.io | false | crates.io database dump | Yes |
Repository803 stars, 74 forks, 28 contributors, 920 commits. Stars alone never qualify a project.
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| GitHub stars | 803 | GitHub repository | Yes — one part of the repository route | |
| GitHub forks | 74 | GitHub repository | Yes — one part of the repository route | |
| Contributors with a GitHub account | 28 | GitHub contributors | Yes — one part of the repository route | |
| Commits on the default branch | 920 | GitHub repository | No | |
| Repository's main crate left out of the entry | none | crates.io database dump | Yes |
Facts that never count
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| License | MIT | crates.io database dump | No | |
| Runs on, from listed crates and their direct dependencies | GPU support unknown | crates.io database dump | No | |
| What shows each backend | no dependency or feature matches a backend row | crates.io database dump | No | |
| Native code, from listed crates and their dependencies | Binds native code: tree-sitter (feature tree-sitter), libduckdb-sys (feature duckdb), rdkafka-sys (feature kafka), tree-sitter-language (feature tree-sitter) | crates.io database dump | No | |
| Python bindings, from direct dependencies of listed crates | No Python binding crate found | crates.io database dump | No | |
| Crates that depend on a listed crate directly | 7 | crates.io database dump | No |
Corrections and review history
No correction applies to this entry.
Judgments
A judgment enters only through an approved issue and a merged pull request.
No judgment applies to this entry.