Install in Claude Code
Copygit clone --depth 1 https://github.com/2FastLabs/agent-squad /tmp/agent-squad-typescript && cp -r /tmp/agent-squad-typescript/typescript ~/.claude/skills/agent-squad-typescriptThen start a new Claude Code session; the skill loads automatically.
Definition
SKILL.md
# agent-squad TypeScript — assistant guide
Node.js / TypeScript multi-agent orchestration framework (npm package `agent-squad`). All public
symbols are exported from a single barrel `typescript/src/index.ts`. This file is guidance and a
map — **not an API reference**. Read exact signatures from
`typescript/src/` and worked recipes from `docs/src/content/docs/`; this file tells you *what to
use, when, and what to watch out for*.
## When to use what
- **One assistant** → a single `Agent` subclass + `AgentSquad` with no routing. Or skip the
orchestrator entirely and call `agent.processRequest(...)` directly.
- **Several specialists** → multiple agents registered with `orchestrator.addAgent(agent)`, a
classifier routes each turn.
- **Answers must not drift from data** (prices, balances, live lookups) → `GroundedAgent`: a
gatherer LLM calls tools, an isolated presenter LLM speaks only from the curated results.
- **Fixed pipeline** → `ChainAgent`: each agent's output is the next agent's input.
- **One lead LLM coordinating a team** → `SupervisorAgent`: the lead calls sub-agents as tools.
- **External tools via MCP** → `MCPToolProvider` (async factory pattern, optional peer dep).
- **RAG context** → attach a `Retriever` to any agent that supports `retriever?` in its options.
## How to install
```bash
npm install agent-squad
```
Optional peer dependencies — install only what you use:
| Package | Used by |
|---|---|
| `@aws-sdk/client-bedrock-runtime` | `BedrockLLMAgent`, `BedrockClassifier` (already a hard dep in current releases) |
| `@anthropic-ai/sdk` | `AnthropicAgent`, `AnthropicClassifier` (already a hard dep) |
| `openai` | `OpenAIAgent`, `OpenAIClassifier` (already a hard dep) |
| `@modelcontextprotocol/sdk` | `MCPToolProvider` — lazy `await import()` at connect time |
| `@dakera-ai/dakera` | `DakeraRetriever` — lazy `require()` at construction time |
`@modelcontextprotocol/sdk` and `@dakera-ai/dakera` are the only two true optional peer deps;
everything else ships as a hard dependency at the moment.
## How a turn works
`routeRequest` is the single entry point. It classifies the input, dispatches to the selected
agent, saves the exchange, and returns an `AgentResponse`. The response is either a plain string or
a Node.js `Transform` stream:
```typescript
import { AgentSquad, BedrockLLMAgent, BedrockClassifier } from 'agent-squad';
const orchestrator = new AgentSquad({
classifier: new BedrockClassifier(), // default when omitted
// storage: new DynamoDbChatStorage(...),
// config: { LOG_AGENT_CHAT: true, MAX_MESSAGE_PAIRS_PER_AGENT: 50 },
});
orchestrator.addAgent(new BedrockLLMAgent({
name: 'Tech Support',
description: 'Handles technical questions about software and hardware',
streaming: true,
}));
const response = await orchestrator.routeRequest(
userInput,
userId,
sessionId,
additionalParams // optional Record<string, any>
);
if (response.streaming) {
// response.output is an AccumulatorTransform (Node.js Transform)
for await (const chunk of response.output) {
process.stdout.write(chunk);
}
} else {
// response.output is a string
console.log(response.output);
// response.thinking? is set when the agent used extended thinking
}
// response.metadata: { agentId, agentName, userId, sessionId, userInput, additionalParams }
```
`routeRequest` never throws — it catches all errors and returns them as a non-streaming
`AgentResponse` with the error string in `output` (configurable via `GENERAL_ROUTING_ERROR_MSG_MESSAGE`).
## The pieces
### Orchestrator: `AgentSquad`
```typescript
new AgentSquad(options?: OrchestratorOptions)
```
Key `OrchestratorOptions` fields:
| Field | Default | Notes |
|---|---|---|
| `classifier` | `new BedrockClassifier()` | Any `Classifier` subclass |
| `storage` | `new InMemoryChatStorage()` | Any `ChatStorage` subclass |
| `defaultAgent` | `undefined` | Used when classifier returns no match and `USE_DEFAULT_AGENT_IF_NONE_IDENTIFIED` is true |
| `config.USE_DEFAULT_AGENT_IF_NONE_IDENTIFIED` | `true` | Fall back to `defaultAgent` or return `NO_SELECTED_AGENT_MESSAGE` |
| `config.MAX_MESSAGE_PAIRS_PER_AGENT` | `100` | Per-agent history cap (pairs = user+assistant) |
| `config.MAX_RETRIES` | `3` | Classifier retries on bad XML response |
| `config.LOG_AGENT_CHAT` | `false` | |
Useful methods: `addAgent(agent)`, `setDefaultAgent(agent)`, `getDefaultAgent()`,
`getAllAgents()`, `analyzeAgentOverlap()`, `classifyRequest(...)`, `agentProcessRequest(...)`.
The classifier is exposed as a public field (`orchestrator.classifier`) so its system prompt can
be overridden after construction.
### Agents
All agents extend `Agent` and require at minimum `{ name, description }` in their options.
**`agent.id`** is derived automatically from `name`: non-alphanumeric stripped, spaces → hyphens,
lowercased. "Tech Support" → `"tech-support"`. This is the key used for storage and classifier
matching — it must be stable across restarts.
| Class | Options type | Notes |
|---|---|---|
| `BedrockLLMAgent` | `BedrockLLMAgentOptions` | Bedrock Converse API; supports `streaming`, `modelId`, `inferenceConfig`, `guardrailConfig`, `reasoningConfig`, `retriever`, `toolConfig`, `customSystemPrompt`, `client`, `callbacks` |
| `AnthropicAgent` | `AnthropicAgentOptions` | Direct Anthropic SDK; similar options shape |
| `OpenAIAgent` | `OpenAIAgentOptions` | OpenAI Chat Completions |
| `AmazonBedrockAgent` | `AmazonBedrockAgentOptions` | Amazon Bedrock Agents (pre-built agents, not Converse) |
| `BedrockInlineAgent` | `BedrockInlineAgentOptions` | Bedrock inline agents |
| `BedrockFlowsAgent` | `BedrockFlowsAgentOptions` | Bedrock Flows |
| `LambdaAgent` | `LambdaAgentOptions` | Invokes a Lambda function as an agent |
| `LexBotAgent` | `LexBotAgentOptions` | Amazon Lex V2 bot |
| `ChainAgent` | `ChainAgentOptions` | Fixed pipeline; `agents: Agent[]`, `defaultOutput?` |
| `SupervisorAgent` | `SupervisorAgentOptions` | Lead + team; `leadAgenMore from this repository