Build autonomous AI agents in Swift β The agent framework for Apple platforms and Linux servers.
SwiftAgents provides everything you need to build AI agents: autonomous reasoning, tool use, memory systems, and multi-agent orchestration. Built natively for Swift 6.2 with full concurrency safety.
- Agents β ReAct, PlanAndExecute, and ToolCalling patterns
- Tools β Type-safe tool creation with
@Toolmacro - Memory β Conversation, summary, and vector memory systems
- Multi-Agent β Supervisor routing, chains, and parallel execution
- Streaming β Real-time event streaming for responsive UIs
- Guardrails β Input/output validation for safe AI interactions
- MCP β Model Context Protocol integration
- Cross-Platform β iOS, macOS, watchOS, tvOS, visionOS, and Linux
dependencies: [
.package(url: "https://github.com/chriskarani/SwiftAgents.git", from: "1.0.0")
]Add to your target:
.target(name: "YourApp", dependencies: ["SwiftAgents"])File β Add Package Dependencies β https://github.com/chriskarani/SwiftAgents.git
import SwiftAgents
// Initialize logging once at startup
Log.bootstrap()
// Create your inference provider
let provider = MyInferenceProvider()
// Build and run an agent
let agent = ReActAgent.Builder()
.inferenceProvider(provider)
.instructions("You are a helpful assistant.")
.build()
let result = try await agent.run("What is the capital of France?")
print(result.output) // "The capital of France is Paris."Create tools using the @Tool macro:
@Tool("Calculate mathematical expressions")
struct CalculatorTool {
@Parameter("The math expression to evaluate")
var expression: String
func execute() async throws -> Double {
// Your calculation logic
let result = try evaluate(expression)
return result
}
}
// Add tools to your agent
let agent = ReActAgent.Builder()
.inferenceProvider(provider)
.instructions("You are a math assistant.")
.addTool(CalculatorTool())
.build()
let result = try await agent.run("What is 25% of 200?")
print(result.output) // "50"Maintain conversation context across interactions:
let memory = ConversationMemory(maxMessages: 100)
let agent = ReActAgent.Builder()
.inferenceProvider(provider)
.memory(memory)
.instructions("You are a friendly assistant.")
.build()
// First message
let r1 = try await agent.run("My name is Alice.")
print(r1.output) // "Nice to meet you, Alice!"
// Agent remembers context
let r2 = try await agent.run("What's my name?")
print(r2.output) // "Your name is Alice."Stream agent execution in real-time:
for try await event in agent.stream("Explain quantum computing") {
switch event {
case .thinking(let thought):
print("Thinking: \(thought)")
case .toolCalling(let call):
print("Using tool: \(call.toolName)")
case .chunk(let text):
print(text, terminator: "")
case .completed(let result):
print("\nDone in \(result.duration)")
case .failed(let error):
print("Error: \(error)")
default:
break
}
}See docs/streaming.md for SwiftUI integration examples.
Route requests to specialized agents:
// Create specialized agents
let mathAgent = ReActAgent.Builder()
.inferenceProvider(provider)
.addTool(CalculatorTool())
.instructions("You are a math specialist.")
.build()
let weatherAgent = ReActAgent.Builder()
.inferenceProvider(provider)
.addTool(WeatherTool())
.instructions("You are a weather specialist.")
.build()
// Create supervisor with intelligent routing
let supervisor = SupervisorAgent(
agents: [
(name: "math", agent: mathAgent, description: mathDesc),
(name: "weather", agent: weatherAgent, description: weatherDesc)
],
routingStrategy: LLMRoutingStrategy(inferenceProvider: provider)
)
// Supervisor routes to the right agent
let result = try await supervisor.run("What's 15 Γ 23?")
// β Routes to math agentSee docs/orchestration.md for chains, parallel execution, and handoffs.
Persist conversation history:
// In-memory session (ephemeral)
let session = InMemorySession(sessionId: "user_123")
try await agent.run("Remember: my favorite color is blue", session: session)
try await agent.run("What's my favorite color?", session: session)
// β "Your favorite color is blue."
// Persistent session (survives app restart - Apple platforms)
#if canImport(SwiftData)
let persistentSession = try PersistentSession.persistent(sessionId: "user_123")
#endifSee docs/sessions.md for session operations and persistence.
Validate inputs and outputs for safety:
let inputGuardrail = ClosureInputGuardrail(name: "ContentFilter") { input, _ in
if containsProhibitedContent(input) {
return .tripwire(message: "Prohibited content detected")
}
return .passed()
}
let outputGuardrail = ClosureOutputGuardrail(name: "PIIRedactor") { output, _, _ in
// Redact sensitive info from output
let redacted = redactSensitiveInfo(output)
return .passed(metadata: ["redacted": .bool(redacted != output)])
}
let agent = ReActAgent.Builder()
.inferenceProvider(provider)
.inputGuardrails([inputGuardrail])
.outputGuardrails([outputGuardrail])
.build()See docs/guardrails.md for safety patterns.
Connect to Model Context Protocol servers:
// Connect to MCP servers
let client = MCPClient()
let server = HTTPMCPServer(name: "my-server", baseURL: serverURL)
try await client.addServer(server)
// Get all tools from connected servers
let mcpTools = try await client.getAllTools()
// Use MCP tools with your agent
let agent = ReActAgent.Builder()
.inferenceProvider(provider)
.tools(mcpTools)
.build()See docs/mcp.md for server implementation.
Build robust agents with failure handling:
let resilientAgent = agent
.withRetry(.exponentialBackoff(maxAttempts: 3))
.withCircuitBreaker(threshold: 5, resetTimeout: .seconds(60))
.withFallback(backupAgent)
.withTimeout(.seconds(30))See docs/resilience.md for circuit breakers and retry policies.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Your Application β
β (iOS, macOS, watchOS, tvOS, visionOS, Linux) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β SwiftAgents β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
β β Agents β β Memory β β Tools β β
β β ReAct, Plan β β Conversationβ β @Tool macro β β
β β ToolCalling β β Vector, Sum β β Registry β β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
β βOrchestrationβ β Guardrails β β MCP β β
β β Supervisor β β Input/Outputβ β Client/Srv β β
β β Chains β β Validation β β Protocol β β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β InferenceProvider Protocol β
β (Foundation Models / OpenRouter / Custom LLMs) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Cross-Platform: Core framework works on all platforms. SwiftData persistence is Apple-only.
| Topic | Description |
|---|---|
| Agents | Agent types, configuration, @Agent macro |
| Tools | Tool creation, @Tool macro, ToolRegistry |
| Memory | Memory systems and persistence backends |
| Sessions | Session management and history |
| Orchestration | Multi-agent patterns and handoffs |
| Streaming | Event streaming and SwiftUI integration |
| Observability | Tracing, metrics, and logging |
| Resilience | Circuit breakers, retry, fallbacks |
| Guardrails | Input/output validation |
| MCP | Model Context Protocol integration |
| DSL | Operators and builders |
| Providers | InferenceProvider implementations |
- Swift: 6.2+
- Apple Platforms: iOS 17+, macOS 14+, watchOS 10+, tvOS 17+, visionOS 1+
- Linux: Ubuntu 22.04+ with Swift 6.2
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make changes following Swift 6.2 concurrency guidelines
- Add tests for new functionality
- Run
swift testandswift package plugin swiftformat - Submit a Pull Request
See CONTRIBUTING.md for details.
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Twitter: @ckarani7
SwiftAgents is released under the MIT License. See LICENSE for details.
Built with Swift for Apple platforms and Linux servers.