Skip to main content
ClaudeWave
Skill7.8k repo starsupdated 3d ago

agent-squad-typescript

>-

Install in Claude Code
Copy
git clone --depth 1 https://github.com/2FastLabs/agent-squad /tmp/agent-squad-typescript && cp -r /tmp/agent-squad-typescript/typescript ~/.claude/skills/agent-squad-typescript
Then start a new Claude Code session; the skill loads automatically.

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; `leadAgen