Extending the framework
AgentSquad is protocol-first: nearly every moving part is an interface with a built-in conformance you can swap out. If a built-in doesn’t fit, implement the protocol and pass your type in — nothing else changes.
Each area has an Overview (the protocol), one or more Built-in pages, and a Custom page with a worked, compile-ready implementation.
| You want to customize | Protocol | Built-in(s) | Custom example |
|---|---|---|---|
| An agent (own model loop, rules, API) | AgentProtocol | Agent, GroundedAgent | Custom agent |
| Routing between agents | Classifier | LLMClassifier | Custom classifier |
| Tools from any source | ToolProvider | MCP, native Swift | Custom tool provider |
| A different MCP SDK | MCPClient | SDKMCPClient | Custom client |
| An LLM connector (non-OpenAI API) | LLMClient | ChatCompletionsClient | Custom connector |
| The HTTP layer under the OpenAI client | ChatCompletionsTransport | URLSession default | Custom connector |
| Chat persistence | ChatStorage | In-memory, File, Device | Custom store |
| Where traces go | Tracer | OSLogTracer, ProcessingTracer | Custom tracing |
| Span export | TraceExporter | OTLPExporter | Custom tracing |
| Span batching/processing | SpanProcessor | BatchSpanProcessor | Custom tracing |
| Redacting trace data | Redactor | default | Custom tracing |
| Shaping tool output for the presenter | ToolOutputCurator | DataBlock/PerTool curators | Custom curator |
| The realtime voice socket | RealtimeTransport | WebSocket transport | Custom transport |
| Audio capture / playback | AudioInput / AudioOutput | MicCapture, AudioPlayback | Custom audio |
The shape of every extension
Section titled “The shape of every extension”All three runtimes follow the same contract: implement the protocol, hand the instance to the type
that consumes it (the Orchestrator, an agent, or a voice assistant), and the framework treats your
type exactly like a built-in. Protocols are Sendable (often Actor-bound) so your conformance must
honor the declared concurrency — match the async/throws/isolation annotations in the source.