Model or dataset
2FastLabs/agent-squad avatar
2FastLabs/agent-squad

Agent Squad: Classifier-Routed Multi-Agent Orchestration in Python, TypeScript and Swift

Flexible and powerful framework for managing multiple AI agents and handling complex conversations

7,762 stars739 forksSwiftApache-2.0

At a glance

What is it?
Agent Squad routes each user turn to one of your specialized agents using a classifier that reads agent descriptions and conversation history. The Python and TypeScript runtimes run in the cloud; the newer Swift runtime runs the same orchestration model on device. The interesting part is the routing seam, and the interesting limitation is what happens when routing goes wrong.
Who is it for?
Adopt Agent Squad if you already have several distinct agents and want a shared routing and context layer rather than a single monolithic prompt, and if you are willing to own the classifier's prompt and the storage backend. Do not adopt it if you need deterministic dispatch, since the routing decision is made by a model reading agent descriptions.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Swift, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The routing problem Agent Squad is built around

Most teams that end up with several agents do not start there. They start with one prompt, then add a second agent for a different domain, then a third, and suddenly the entry point has to decide which one should answer. Agent Squad addresses exactly that decision. The README describes the project as a framework that "routes each user query to the most suitable of your specialized agents and maintains conversation context across them." The unit of work is a turn: one user input, one selected agent, one stored exchange.

The audience is narrow but real. You need more than one agent with distinguishable responsibilities, you need the selection to depend on conversation context rather than a static keyword rule, and you want the same model available in more than one language runtime. A single-agent chatbot has no routing problem to solve, and a workflow with fixed steps has no need for a classifier at all. Agent Squad is for the middle case: several specialists, one entry point, ambiguous queries.

What actually happens between input and response

The README gives a four-step flow. User input is analyzed by a Classifier. The Classifier uses the agents' descriptions and the conversation history to select the best agent for the turn. The selected Agent processes the input, calling tools as needed. The Orchestrator saves the exchange and returns the response.

That ordering matters. Agent selection is not a lookup on a routing table. It is a model call that receives your agent descriptions as part of its input, which means the quality of your routing is a function of how you wrote those description strings. The example in the README uses a description like "Specializes in technology: software, hardware, AI, cybersecurity, cloud." Two agents whose descriptions both mention cloud will produce ambiguous routing, and there is no rule engine underneath to break the tie. The classifier is the tie-breaker.

The Orchestrator is the object you construct and hold. In TypeScript it is `new AgentSquad()`, in Python `AgentSquad()`, in Swift `Orchestrator(agents:store:)`. You register agents on it, call a route method, and receive either a stream or a final payload. Context is stored per user and per session, which is why every route call in the examples takes a `userId` and a `sessionId`.

The two patterns layered on top: SupervisorAgent and GroundedAgent

SupervisorAgent changes the shape of the graph. Instead of one classifier picking one agent, a lead agent coordinates a team "in parallel using an agent-as-tools architecture, maintaining shared context and delivering one coherent response." The README states it supports dynamic delegation of subtasks and works with all agent types, and that it can itself be registered in the classifier, which is how you build hierarchical teams. That last detail is the design decision worth noting: the supervisor is not a separate primitive, it is an agent that happens to hold other agents, so it composes with the routing layer rather than replacing it.

GroundedAgent is a different kind of intervention. It splits one answer across two models. A gatherer calls your tools and sees the raw results but "never speaks to the user." An isolated presenter then writes the reply "from the curated tool output alone: no tools, no tool tra..." (the README text is truncated at this point, so the exact list of what the presenter is denied cannot be confirmed from the supplied material). The stated intent is that answers cannot drift from your data. This is a cost trade: two model calls per response instead of one, in exchange for a narrower channel between tool output and user-visible text.

Installing and wiring it up in each runtime

TypeScript installs with `npm install agent-squad` and imports `AgentSquad` and `BedrockLLMAgent`. You add an agent with `orchestrator.addAgent(...)`, passing a name, a description and `streaming: true`, then call `orchestrator.routeRequest("What is AWS Lambda?", "user123", "session456")`. The response carries `metadata.agentName` so you can log which agent was chosen, and if `response.streaming` is true you iterate `response.output` as an async iterator.

Python installs with `pip install "agent-squad[aws]"`, and the README notes the alternatives `[anthropic]`, `[openai]` and `[all]`. The extra is how you select provider dependencies. The Python route call is `await orchestrator.route_request("What is AWS Lambda?", "user123", "session456", {}, True)`, with a positional dictionary and a boolean, and the stream yields `AgentStreamResponse` objects whose `.text` you print. Note the asymmetry: Python uses `agent_name` in metadata, TypeScript uses `agentName`.

Swift is added as a package dependency pointing at the repository with `branch: "main"` rather than a tagged version, which is worth flagging. You construct an `Agent` with a `ChatCompletionsClient(model: "gpt-4o-mini", apiKey: apiKey)`, build an `Orchestrator(agents:store:)` with `try DeviceChatStorage(userId: "u1")`, and consume `orchestrator.route(.text(...), userId:sessionId:)` as an async sequence of events, matching on `.textDelta(let token)`. The Swift runtime requires iOS 16+ or macOS 14+.

Where the classifier approach breaks down

The classifier is also the failure mode. Because routing is a model judgement over natural-language descriptions, it is probabilistic in a way a dispatch table is not. If a user asks something that legitimately spans two agents, the framework picks one and the other never sees the turn. There is no documented arbitration step for that case in the material provided.

A second constraint is that routing depends on conversation history. That is a feature for follow-up questions and a liability for long sessions, because the same input can route differently at turn two and turn forty. If your agents are not truly interchangeable in quality, that variance is visible to users as inconsistent answers.

Third, the storage backend is a seam you must fill. The Python and TypeScript examples construct the orchestrator with no storage argument at all, and the Swift example passes an explicit `DeviceChatStorage(userId:)`. The README describes context management as a feature and extensibility of storage as a design goal, but the supplied material does not state what the default storage does across process restarts. Treat persistence as something to verify rather than assume.

How it differs from LangGraph and similar graph frameworks

LangGraph, and graph-oriented orchestration libraries generally, ask you to declare nodes and edges: the control flow is authored, and the model operates inside the nodes you defined. Agent Squad inverts that. You register agents with descriptions and let a classifier decide the edge at runtime. The difference shows up when requirements change. In a graph framework, adding a specialist means adding a node and an edge condition. In Agent Squad it can mean adding an agent with a well-written description and letting the classifier learn to prefer it, which is less code and less certainty.

That trade cuts both ways. Graph frameworks give you a traceable path you can assert on in a test. Agent Squad gives you `metadata.agentName` after the fact, which tells you what was chosen but not why. If you need reproducible routing for compliance or debugging, the authored-graph approach fits better. If your agent set changes often and you would rather not maintain edge logic, the classifier approach costs less to keep current.

Maintenance, licensing and the repository move

The README carries a migration notice: the project was previously hosted at `awslabs/agent-squad`, is now maintained at `2fastlabs/agent-squad`, and was formerly named `multi-agent-orchestrator`. The README asks readers to update bookmarks, clone URLs and dependencies. If you have an existing dependency pinned to the old path, that rename is the first thing to check, because a moved repository affects both your package manager resolution and any CI configuration that references the old URL.

Release cadence is visible in the recent tags: `typescript_1.1.4` and `python_1.1.3` both on 2026-07-14, with `typescript_1.1.3` earlier the same day. The runtime versions are tracked separately, which means Python and TypeScript can drift even though the README claims they "maintain feature parity." There is no Swift version tag in the supplied release list, so the Swift runtime appears to be consumed from `main` rather than a release, consistent with the `branch: "main"` dependency shown in the quick start.

The licence is Apache-2.0, which permits commercial use and modification and includes a patent grant. Apache-2.0 also requires that you preserve copyright and licence notices and state significant changes if you redistribute modified source. This is a description of the licence text, not legal advice; check the `LICENSE` file and your own obligations before shipping a modified fork.

Editorial conclusion

Adopt Agent Squad if you already have several distinct agents and want a shared routing and context layer rather than a single monolithic prompt, and if you are willing to own the classifier's prompt and the storage backend. Do not adopt it if you need deterministic dispatch, since the routing decision is made by a model reading agent descriptions. Before committing, verify two things in your own environment: how the classifier behaves when two agent descriptions overlap, and whether your chosen storage backend survives a process restart, because the README documents the storage seam but not a default persistence guarantee.

Official sources

  1. 2FastLabs/agent-squad on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Community notes

Community notes