Skip to content

Quick start

Everything below compiles and runs from the command line. You need Swift 6.2+ (Xcode 26+) and an OpenAI API key.

6.0
import PackageDescription
let package = Package(
name: "quickstart",
platforms: [.macOS(.v14)],
dependencies: [
.package(url: "https://github.com/2FastLabs/agent-squad", branch: "main")
],
targets: [
.executableTarget(name: "quickstart", dependencies: [
.product(name: "AgentSquad", package: "agent-squad")
])
]
)
import AgentSquad
import Foundation
guard let apiKey = ProcessInfo.processInfo.environment["OPENAI_API_KEY"] else {
fatalError("set OPENAI_API_KEY")
}
// LLM client — any OpenAI-compatible endpoint
let model = ChatCompletionsClient(model: "gpt-4o-mini", apiKey: apiKey)
// One agent: name + description drive the default system prompt
let agent = Agent(name: "Shop", description: "Shopping assistant", model: model)
// Orchestrator with no classifier — the single agent always handles every turn
let orchestrator = Orchestrator(
agents: [agent],
store: try DeviceChatStorage(userId: "u1", inMemory: true)
)
// route(_:userId:sessionId:) returns an AsyncThrowingStream<AgentEvent, any Error>
for try await event in orchestrator.route(
.text("wireless headphones under €100?"),
userId: "u1",
sessionId: "s1"
) {
if case .textDelta(let token) = event { print(token, terminator: "") }
}
print()
Terminal window
OPENAI_API_KEY=sk-… swift run

Add a second agent and an LLMClassifier — the call site is identical:

let shop = Agent(name: "Shop", description: "Product search, prices, recommendations.", model: model)
let support = Agent(name: "Support", description: "Orders, returns, and account help.", model: model)
let orchestrator = Orchestrator(
agents: [shop, support], // first agent is the default / fallback
classifier: LLMClassifier(model: model), // picks the agent for each turn
store: try DeviceChatStorage(userId: "u1", inMemory: true)
)
for try await event in orchestrator.route(
.text("where is my order #1234?"),
userId: "u1",
sessionId: "s1"
) {
if case .textDelta(let token) = event { print(token, terminator: "") }
}

LLMClassifier uses the same LLMClient type as the agents. You can pass a separate, cheaper model for routing if you like:

let router = ChatCompletionsClient(model: "gpt-4o-mini", apiKey: apiKey)
LLMClassifier(model: router)
TypeRole
ChatCompletionsClientLLMClient for any OpenAI-compatible endpoint (OpenAI, Azure, Groq, OpenRouter, Ollama, …)
AgentSingle-LLM agent; accepts optional tools: and a custom systemPrompt:
OrchestratorDrives a turn end-to-end: classify → run agent → stream events → persist
LLMClassifierRoutes turns to agents via a select_agent tool call
AgentEvent.textDeltaToken-by-token text streamed from the agent
  • Add tools to an agent — see Agents and Tools.
  • Swap Agent for GroundedAgent for hallucination-resistant answers — see GroundedAgent.
  • Understand every event the stream can emit — see Messages & events.
  • Point ChatCompletionsClient at a different provider — see LLM clients.
  • Persist chat history across sessions — see Chat history.
  • Observe what happens inside a turn — see Tracing.