Skip to content
HN On Hacker News β†—

GitHub - christopherkarani/Swarm: πŸ¦β€πŸ”₯ Agent Orchestration Framework , MacOS/iOS/Linux Pure Swift 6.3

β–² 25 points β€’ 4 comments β€’ by christkarani β€’ 4mo ago β€’ HN discussion β†—

Pangram verdict Β· v3.3

We believe that this document is a mix of AI-generated, AI-assisted, and human-written content

83 %

AI likelihood Β· overall

Mixed
15% human-written 73% AI-generated
SEGMENTS Β· HUMAN 1 of 6
SEGMENTS Β· AI 4 of 6
WORD COUNT 1,134
PEAK AI % 99% Β· Β§2
Analyzed
Jul 6
backend: pangram/v3.3
Segments scanned
6 windows
avg 189 words each
Distribution
15 / 73%
human / AI fraction
Verdict
Mixed
Pangram v3.3

Article text Β· 1,134 words Β· 6 segments analyzed

Human AI-generated
Β§1 AI Β· 99%

A Swift framework for building agents and multi-agent workflows.

let result = try await Workflow() .step(researchAgent) .step(writerAgent) .run("Summarize the latest WWDC session on Swift concurrency.")

Two agents, one pipeline, compiled to a DAG with crash recovery and Swift concurrency safety. Install .package(url: "https://github.com/christopherkarani/Swarm.git", from: "0.6.0") Quick Start import Swarm

// The @Tool macro generates the JSON schema at compile time @Tool("Looks up the current stock price") struct PriceTool { @Parameter("Ticker symbol") var ticker: String func execute() async throws -> String { "182.50" } }

// Create an agent with unlabeled instructions first and tools in the trailing @ToolBuilder closure let agent = try Agent("Answer finance questions using real data.", configuration: .init(name: "Analyst"), inferenceProvider: .anthropic(key: "{ENV")) { PriceTool() CalculatorTool() }

let result = try await agent.run("What is AAPL trading at?") print(result.output) // "Apple (AAPL) is currently trading at $182.50." That is a working agent with type-safe tool calling. Swarm also supports AGENTS.md and SKILL.md for declarative agent specs and reusable skills β€” see the Getting Started guide for the full workspace layout. Why Swarm

Swift concurrency is part of the surface. Swift 6.2 StrictConcurrency is enabled across the package. Tools stay type-safe. The @Tool macro generates JSON schemas from Swift structs. Workflows can survive crashes. Durable workflow checkpointing lets you resume from an explicit checkpoint ID. Cloud and on-device models use the same abstractions. Foundation Models, Anthropic, OpenAI, Ollama, Gemini, MiniMax, OpenRouter, and MLX all fit the same shape. It is written in Swift all the way down. AsyncThrowingStream, actors, result builders, and macros are first-class here.

Β§2 AI Β· 99%

Examples Capability matrix showcase Swarm now ships with an in-repo capability showcase that exercises the stable surface area in one deterministic matrix:

agents and tools streaming conversation plus session persistence sequential, parallel, routed, and repeat-until workflows handoffs memory on-device workspace loading guardrails resilience helpers durable checkpoint and resume observability MCP discovery and tool bridging provider selection

Run it locally: swift run SwarmCapabilityShowcase list swift run SwarmCapabilityShowcase matrix swift run SwarmCapabilityShowcase run handoff swift run SwarmCapabilityShowcase smoke The deterministic matrix is CI-safe. Live-provider smoke coverage is opt-in through environment variables. See docs/guide/capability-showcase.md for the scenario catalog and smoke-mode details. Optional demos Demo executables are opt-in so the default library graph stays focused on the framework products: SWARM_INCLUDE_DEMO=1 swift build SWARM_INCLUDE_DEMO=1 swift run SwarmDemo SWARM_INCLUDE_DEMO=1 swift run SwarmMCPServerDemo Multi-agent pipeline let researcher = try Agent("Research the topic and extract key facts.", inferenceProvider: .anthropic(key: "sk-...")) { WebSearchTool() }

let writer = try Agent("Write a concise summary from the research.", inferenceProvider: .anthropic(key: "sk-..."))

let result = try await Workflow() .step(researcher) .step(writer) .run("Latest advances in on-device ML") Each agent resolves its own provider. Pass inferenceProvider: per agent (as above), or call await Swarm.configure(provider: .anthropic(apiKey: "...")) once at app startup to share a default across every agent that doesn't specify one. Parallel fan-out let result = try await Workflow() .parallel([bullAgent, bearAgent, analystAgent], merge: .structured) .run("Evaluate Apple's Q4 earnings.") // Three perspectives, merged into one output.

Β§3 AI Β· 98%

Dynamic routing let result = try await Workflow() .route { input in if input.contains("$") { return mathAgent } if input.contains("weather") { return weatherAgent } return generalAgent } .run("What is 15% of $240?") Streaming for try await event in agent.stream("Summarize the changelog.") { switch event { case .output(.token(let t)): print(t, terminator: "") case .tool(.completed(let call, _)): print("\n[tool: \(call.toolName)]") case .lifecycle(.completed(let r)): print("\nDone in \(r.duration)") case .lifecycle(.failed(let error)): print("\nError: \(error)") default: break // Other events include .output(.thinking(...)), .handoff(...), .observation(...), and .lifecycle(.iterationStarted(...)). } }

More examples Semantic memory let agent = try Agent("You remember past conversations.", inferenceProvider: .anthropic(key: "sk-..."), memory: .vector(embeddingProvider: myEmbedder, similarityThreshold: 0.75)) { // tools } Guardrails let agent = try Agent("You are a helpful assistant.", inputGuardrails: [InputGuard.maxLength(5000), InputGuard.notEmpty()], outputGuardrails: [OutputGuard.maxLength(2000)]) Closure tools let reverse = FunctionTool( name: "reverse", description: "Reverses a string", parameters: [ToolParameter(name: "text", description: "Text to reverse", type: .string, isRequired: true)] ) { args in let text = try args.require("text", as: String.self) return .string(String(text.reversed())) }

let agent = try Agent("Text utilities.",

Β§4 AI Β· 93%

tools: [reverse]) Crash-resumable workflows let workflow = Workflow() .step(monitor) .durable.checkpoint(id: "monitor-v1", policy: .everyStep) .durable.checkpointing(.fileSystem(directory: checkpointsURL))

let resumed = try await workflow.durable.execute("watch", resumeFrom: "monitor-v1") Provider switching // On-device, private, no API key needed let local = try Agent("Be helpful.", inferenceProvider: .foundationModels())

// Cloud let cloud = try Agent("Be helpful.", inferenceProvider: .anthropic(key: k))

// Or swap at runtime via environment let modified = agent.environment(\.inferenceProvider, .ollama(model: "mistral")) Conversation let conversation = Conversation(with: agent)

let response1 = try await conversation.send("What's the weather?") let response2 = try await conversation.send("And tomorrow?") // Context preserved

for message in await conversation.messages { print("\(message.role): \(message.text)") }

How Swarm Compares

Swarm LangChain AutoGen

Language Swift 6.2 Python Python

Data race safety Compile-time Runtime Runtime

On-device LLM Foundation Models n/a n/a

Execution model Typed Workflow graph Loop-based Loop-based

Crash recovery Checkpoints n/a Partial

Type-safe tools @Tool macro (compile-time) Decorators (runtime) Runtime

Streaming AsyncThrowingStream Callbacks Callbacks

iOS / macOS native First-class n/a n/a

What's Included

Agents Agent struct with @ToolBuilder trailing closure, AgentRuntime protocol

Workflows Workflow: .step(), .parallel(), .route(), .repeatUntil(), .timeout()

Tools @Tool macro, FunctionTool, @ToolBuilder, parallel execution

Memory .conversation(maxMessages:), .vector(embeddingProvider:similarityThreshold:maxResults:), .slidingWindow(maxTokens:), .summary(configuration:summarizer:), .hybrid(configuration:summarizer:)

Guardrails InputGuard.maxLength(), InputGuard.notEmpty(), InputGuard.custom(), OutputGuard.maxLength(),

Β§5 Human Β· 24%

OutputGuard.custom()

Conversation Conversation actor for stateful multi-turn dialogue

Resilience 7 backoff strategies, circuit breaker, fallback chains, rate limiting

Observability AgentObserver, Tracer, SwiftLogTracer, per-agent token metrics

MCP Model Context Protocol client and server support

Providers Foundation Models, Anthropic, OpenAI, Ollama, Gemini, MiniMax, OpenRouter, MLX via Conduit

Macros @Tool, @Parameter, @Traceable, #Prompt

Architecture β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Your Application β”‚ β”‚ iOS 26+ Β· macOS 26+ Β· Linux (Ubuntu 22.04+) β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ Workflow Β· Conversation Β· .run() Β· .stream() β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ Agents Memory Tools β”‚ β”‚ Agent (struct) Memory factories @Tool macro β”‚ β”‚ AgentRuntime Conversation FunctionTool β”‚ β”‚ (dot-syntax) @ToolBuilder β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ InputGuard Β· OutputGuard Β· Resilience Β· Observability Β· MCPβ”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ Durable Graph Runtime (internal) β”‚ β”‚ Workflow Graph Β· Checkpointing Β· Deterministic retry β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€

Β§6 Mixed Β· 68%

β”‚ InferenceProvider (pluggable) β”‚ β”‚ Foundation Models Β· Anthropic Β· OpenAI Β· Ollama Β· OpenRouterβ”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Requirements

Platform Minimum

Swift 6.2+

iOS 26.0+

macOS 26.0+

tvOS 26.0+

Linux Ubuntu 22.04+ with Swift 6.2

The default Swarm graph is CI-tested on Ubuntu with Swift 6.2. Apple-only features such as Foundation Models, SwiftData, OSLog, and some built-in tool behavior are unavailable or different on Linux; cloud providers and Ollama use the shared InferenceProvider surface. Documentation

Getting Started Installation, first agent, workflows

OpenTelemetry Tracing Export agent and LLM spans, with optional trace header injection for provider HTTP requests

API Reference Every type, protocol, and API

Front-Facing API Public API surface

Why Swarm? Design philosophy and architecture

Contributing

Fork β†’ branch β†’ swift test β†’ PR All public types must be Sendable; the compiler enforces it Format with swiftformat Sources Tests --lint --config .swiftformat

Bug reports and feature requests: GitHub Issues Community GitHub Issues Β· Discussions Β· @ckarani7 If Swarm saves you time, a star helps others find it. License Released under the MIT License.