Squad.Agents.AI
0.5.1-preview.8
dotnet add package Squad.Agents.AI --version 0.5.1-preview.8
NuGet\Install-Package Squad.Agents.AI -Version 0.5.1-preview.8
<PackageReference Include="Squad.Agents.AI" Version="0.5.1-preview.8" />
<PackageVersion Include="Squad.Agents.AI" Version="0.5.1-preview.8" />
<PackageReference Include="Squad.Agents.AI" />
paket add Squad.Agents.AI --version 0.5.1-preview.8
#r "nuget: Squad.Agents.AI, 0.5.1-preview.8"
#:package Squad.Agents.AI@0.5.1-preview.8
#addin nuget:?package=Squad.Agents.AI&version=0.5.1-preview.8&prerelease
#tool nuget:?package=Squad.Agents.AI&version=0.5.1-preview.8&prerelease
Squad.Agents.AI
Preview package.
Squad.Agents.AIis a0.1.0-previewNuGet package for early adopters. It targetsnet10.0and depends on preview Microsoft Agent Framework / GitHub Copilot SDK packages, so APIs may change before a stable release.
What it does
Squad.Agents.AI exposes a Squad team as a Microsoft Agent Framework AIAgent. SquadAgent composes the Squad CLI through the GitHub Copilot SDK, delegates MAF sessions/runs/streaming to the inner Copilot agent, and gives .NET consumers a DI-friendly wrapper instead of hand-rolling CLI process setup.
Public surface in this preview:
SquadAgent— sealedAIAgentwrapper over the Copilot-backed inner agent. Supports both non-streaming and streaming viaRunStreamingAsync.SquadAgentOptions— team root, CLI path/args, environment, token, logging, instruction settings, and aConfigureCopilotClientdelegate for advanced SDK customization.SquadConnectionFactory— parses PATH orsquad://connection strings into options.SquadServiceCollectionExtensions— registersSquadAgentand baseAIAgentin DI, with standard and keyed overloads.
Repository: https://github.com/bradygaster/squad
Install
dotnet add package Squad.Agents.AI --prerelease
If you are consuming the PR before publish, pack it locally and add the generated package source:
dotnet pack src/Squad.Agents.AI/Squad.Agents.AI.csproj -c Release -o nupkgs
dotnet add package Squad.Agents.AI --prerelease --source ./nupkgs
Prerequisites
- .NET 10 SDK.
- GitHub Copilot CLI available on
PATH(copilot --version). - Squad CLI and an initialized Squad team root; see the Squad CLI repo.
- GitHub Copilot authentication through the signed-in user. The quickstart below does not require an app key or environment variable.
Five-line quickstart
using Microsoft.Agents.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Squad.Agents.AI;
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddSquadAgent(o =>
{
o.SquadFolderPath = @"C:\path\to\your\team-root";
});
using var host = builder.Build();
var squad = host.Services.GetRequiredService<AIAgent>();
var session = await squad.CreateSessionAsync();
var response = await squad.RunAsync("What can this Squad team do?", session);
Console.WriteLine(response.Text);
Streaming
SquadAgent supports streaming via the MAF RunStreamingAsync method. The inner Copilot-backed agent streams response updates as they arrive from the CLI process:
var squad = host.Services.GetRequiredService<SquadAgent>();
var session = await squad.CreateSessionAsync();
await foreach (var update in squad.RunStreamingAsync("Summarize the team.", session))
{
Console.Write(update.Text);
}
Keyed DI
Register multiple Squad teams in the same DI container using .NET 8+ keyed services:
builder.Services.AddKeyedSquadAgent("research", o =>
{
o.SquadFolderPath = @"C:\research-team";
});
builder.Services.AddKeyedSquadAgent("platform", o =>
{
o.SquadFolderPath = @"C:\platform-team";
});
// Resolve in a minimal API endpoint:
app.MapGet("/ask-research", async ([FromKeyedServices("research")] SquadAgent agent) =>
{
var session = await agent.CreateSessionAsync();
var response = await agent.RunAsync("What's the latest?", session);
return response.Text;
});
Keyed registrations include AddKeyedSquadAgent overloads for service key, optional connection-string name, and lifetime. Keyed and non-keyed registrations can coexist.
Advanced: ConfigureCopilotClient (BYOK)
Use ConfigureCopilotClient to customize the underlying CopilotClientOptions after Squad applies its standard values. This is the extension point for injecting custom environment variables, providing a BYOK token, or tuning SDK settings:
builder.Services.AddSquadAgent(o =>
{
o.SquadFolderPath = @"C:\team";
o.ConfigureCopilotClient = clientOpts =>
{
// Inject a BYOK token from your own credential store
clientOpts.GitHubToken = myVault.GetSecret("copilot-token");
// Add custom environment variables for the CLI process
clientOpts.Environment = new Dictionary<string, string>
{
["MY_CUSTOM_VAR"] = "value"
};
};
});
Routing guard: Squad enforces a hard routing gate — if the delegate changes
Cwd,CliPath, orCliArgs, the original values are restored and a warning is logged. Configure these viaSquadAgentOptionsinstead.
GitHub Copilot authentication
The default path mirrors the base GitHub Copilot SDK examples: leave GitHubToken and GitHubTokenProvider unset, then run with a locally signed-in GitHub Copilot user. For local development, sign in before running the app, for example with gh auth login, the Copilot CLI sign-in flow, or a Copilot-supported local sign-in that the SDK runtime can access.
The SDK documents the credential priority order in Authenticate Copilot SDK and the broader authentication overview. Explicit tokens and environment variables are supported by the SDK, but they are not required for the minimal happy path.
Use GitHubTokenProvider only when the host owns token retrieval, such as Key Vault, managed identity, or CI secret flow scenarios. Use GitHubToken only when you already have a Copilot-supported token in process and cannot use a provider callback. Use ConfigureCopilotClient when you need full control over the SDK's CopilotClientOptions, including BYOK token injection.
Aspire / configuration path
AddSquadAgent() reads ConnectionStrings:squad through IConfiguration.GetConnectionString("squad"). In environment variables, use ConnectionStrings__squad.
Named registrations support both connection-string conventions:
| Style | Example | Looks up |
|---|---|---|
| Aspire-style direct (tried first) | AddSquadAgent("research-squad") |
ConnectionStrings:research-squad |
| Legacy prefixed fallback | AddSquadAgent("research") |
ConnectionStrings:squad-research |
So when an Aspire AppHost registers a Squad resource via builder.AddSquad("research-squad", ...) and a downstream project does .WithReference(researchSquad), the consumer can resolve the agent with a single builder.Services.AddKeyedSquadAgent("research-squad") call — the SDK finds the Aspire-injected connection string automatically. Existing consumers using the prefixed form continue to work; the SDK tries the literal name first and falls back to squad-{name} if the direct lookup is empty.
Supported connection string forms:
C:\path\to\team-root
squad://localhost?teamRoot=C%3A%5Cteam&cliPath=C%3A%5Ctools%5Ccopilot.exe&cliArgs=--yolo&env=KEY=value
Parsed URI query keys: teamRoot, cliPath, cwd, cliArgs (semicolon-separated), and env (key=value;key2=value2). Unknown URI host/protocol values are reserved for future use.
Coordinator agent selection
SquadAgent exists to wrap a Squad coordinator team, so it passes --agent squad to the underlying copilot.exe child process by default. That tells the CLI to load .github/agents/squad.agent.md as the agent definition — which is what teaches the coordinator to eager-execute, fan out, and dispatch through the task tool. Without it, the CLI uses its built-in generic agent and the coordinator role-plays responses inline instead of spawning real subagents — producing SDK behavior that does NOT match running copilot --agent squad interactively against the same team root.
| Scenario | What the SDK does |
|---|---|
Default — squad.agent.md exists |
Auto-adds --agent squad |
squad.agent.md not found at .github/agents/ |
Silently skips --agent (graceful degradation for not-yet-initialized teams; logs a Debug message) |
Consumer sets AgentFileName = "data" (and file exists) |
Auto-adds --agent data |
Consumer sets AgentFileName = null |
Skips --agent entirely |
Consumer already supplied --agent X in CliArgs |
Respects the explicit value; does not add a second --agent |
SDK note:
SessionConfigBase.Agentexists but looks up the name in the SDK'sCustomAgentsregistry, NOT in.github/agents/*.agent.mdfiles on disk. The CLI--agentflag is currently the only path that reads the on-disk agent definition.
Subagent observability — first-class OpenTelemetry
Squad.Agents.AI emits one OpenTelemetry Activity per subagent dispatch out of the box. Hosts that subscribe to the activity source see one squad.subagent {Name} span per spawn, with the subagent name as a tag and timeline annotations (squad.subagent.start, squad.subagent.message, squad.subagent.completed, squad.subagent.failed) marking every state transition.
Two-line wiring is all that is required — no manual callback plumbing:
using OpenTelemetry.Trace;
using Squad.Agents.AI;
builder.Services.AddOpenTelemetry()
.WithTracing(t => t.AddSource(SquadAgentDiagnostics.ActivitySourceName));
builder.Services.AddSquadAgent(o => o.SquadFolderPath = @"C:\team");
When the coordinator's task tool spawns specialists, the host's tracer (Jaeger, Zipkin, Application Insights, or the Aspire dashboard's Traces view) shows one squad.subagent span per spawn, each tagged with squad.subagent.name, squad.subagent.display_name, squad.subagent.sdk_agent_id, and squad.subagent.reply_preview — plus timeline events for every lifecycle transition.
Turning telemetry off. Set EmitSubagentActivities = false to suppress Squad's built-in spans (for example, when you want to drive observability entirely from your own callback or avoid double-counting). The OnSubagentTrace callback continues to fire either way — it is the customization seam, independent of telemetry.
builder.Services.AddSquadAgent(o =>
{
o.SquadFolderPath = @"C:\team";
o.EmitSubagentActivities = false; // disable built-in OTel emission
o.OnSubagentTrace = trace => // handle telemetry yourself
{
if (trace.Kind == SquadAgentTraceEventKind.SubagentStarted)
MyMetrics.IncrementSpawn(trace.SubagentName!);
};
});
Key options
| Option | Purpose |
|---|---|
SquadFolderPath |
Squad team root; PATH connection strings set this and Cwd. |
CliPath / CliArgs |
Override the Copilot CLI executable and add extra CLI flags. |
Cwd |
Working directory for the Copilot CLI process; defaults to SquadFolderPath. |
Environment |
Additional environment variables for the CLI process. Excluded from JSON serialization; token-pattern keys are redacted in ToString(). |
GitHubToken |
Advanced direct token escape hatch; excluded from JSON serialization and redacted by ToString(). |
GitHubTokenProvider |
Advanced callback for secure token retrieval; wins over GitHubToken. |
ConfigureCopilotClient |
Advanced delegate for customizing CopilotClientOptions. Routing properties are guarded; see BYOK section. |
TraceEvents |
Enables verbose SDK logging and emits a startup warning when enabled. |
AgentName |
Display name for the resulting AIAgent; defaults to Squad. |
AgentFileName |
Name of the agent definition under .github/agents/{name}.agent.md to load via the CLI's --agent flag. Defaults to "squad". Set to null to skip auto-injection; the file-existence check makes this safe to leave on for not-yet-initialized teams. |
Instructions |
Optional system instructions passed to the inner Copilot agent. |
EmitSubagentActivities |
Whether the SDK opens an OpenTelemetry Activity per subagent dispatch and annotates lifecycle events. Defaults to true. Set to false to handle telemetry from your own OnSubagentTrace callback. |
OnSubagentTrace |
Optional callback invoked for every typed SquadAgentTraceEvent. Independent of EmitSubagentActivities — both can be on simultaneously. |
Security
- Credential redaction:
GitHubTokenandEnvironmentvalues whose keys match*TOKEN*,*KEY*,*SECRET*,*HMAC*,*PASSWORD*, or*CREDENTIAL*are always redacted inToString()output. - JSON safety:
GitHubToken,GitHubTokenProvider,Environment, andConfigureCopilotClientare marked[JsonIgnore]and will not appear in JSON serialization output. - Routing guard: The
ConfigureCopilotClientdelegate cannot changeCwd,CliPath, orCliArgs— changes are silently restored to prevent routing the agent to an unintended CLI process. - TraceEvents warning: Enabling
TraceEventslogs a startup warning because verbose SDK traces may include sensitive operational details. - Avoid hardcoded tokens: Never embed tokens in source code. Use
GitHubTokenProviderfor production token retrieval from Key Vault, managed identity, or similar secure stores.
Notes for v0.1-preview
- Default DI lifetime is scoped. An overload accepts any
ServiceLifetime. - DI registers both
SquadAgentand baseAIAgent(non-keyed). Keyed DI registers bothSquadAgentandAIAgentunder the same key. - Multi-targeting and Aspire telemetry remain candidates for a later preview.
- The package does not validate that
SquadFolderPathexists; consumers should validate their deployment paths. TraceEventscan log sensitive operational details. Keep it off unless debugging.
Package contents
lib/net10.0/Squad.Agents.AI.dlllib/net10.0/Squad.Agents.AI.xmlfor IntelliSense / API docsREADME.mdfor NuGet.org rendering.nuspecmetadata with authors, tags, repository, and readme pointerLICENSEcopied from the repository root
Sample
A runnable console application is included at
src/Squad.Agents.AI/samples/Squad.Agents.AI.Sample/. It demonstrates the four
core integration patterns in one place: basic DI, keyed DI with multiple agents,
the ConfigureCopilotClient BYOK delegate, and streaming via RunStreamingAsync.
Prerequisites
| Prerequisite | Notes |
|---|---|
| .NET 10 SDK | dotnet --version should print 10.x.x |
GitHub Copilot CLI on PATH |
Install from github.com/github/copilot-cli; verify with copilot --version |
| Squad CLI installed | Follow the install guide in the Squad repository README |
| Initialized Squad team root | Run squad init in a directory; this becomes your team root |
| GitHub Copilot authentication | Run gh auth login or copilot auth login once before running the sample |
Set the team root path before running:
# Linux / macOS
export SQUAD_TEAM_ROOT=/path/to/your/team-root
# Windows PowerShell
$env:SQUAD_TEAM_ROOT = "C:\path\to\your\team-root"
Run
Run all four flows in sequence:
dotnet run --project src/Squad.Agents.AI/samples/Squad.Agents.AI.Sample/
Run a single flow (1–4):
dotnet run --project src/Squad.Agents.AI/samples/Squad.Agents.AI.Sample/ -- --flow=1
dotnet run --project src/Squad.Agents.AI/samples/Squad.Agents.AI.Sample/ -- --flow=2
dotnet run --project src/Squad.Agents.AI/samples/Squad.Agents.AI.Sample/ -- --flow=3
dotnet run --project src/Squad.Agents.AI/samples/Squad.Agents.AI.Sample/ -- --flow=4
Flow walkthrough
Flow 1 — Basic DI registration — AddSquadAgent registers SquadAgent and the
base AIAgent interface. Resolves the agent from DI, creates a session, calls
RunAsync, and prints AgentResponse.Text.
Flow 2 — Keyed DI (multiple agents) — AddKeyedSquadAgent registers two agents
under keys "alpha" and "beta". Resolution uses
GetRequiredKeyedService<SquadAgent>("alpha").
Flow 3 — BYOK / ConfigureCopilotClient delegate — the delegate receives
CopilotClientOptions after Squad has applied its defaults. Inject a custom token
or environment variable. The routing gate prevents accidental redirection of
Cwd, CliPath, or CliArgs — configure those on SquadAgentOptions directly.
Flow 4 — Streaming — RunStreamingAsync returns
IAsyncEnumerable<AgentResponseUpdate>. Each update.Text fragment is written to
Console.Write without a newline for live token-by-token output.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
GitHub Copilot CLI was not found on PATH |
copilot binary is missing or not on PATH |
Install from github.com/github/copilot-cli; verify with copilot --version |
Authentication failed / 401 |
Copilot CLI is not signed in | Run gh auth login or copilot auth login |
SquadFolderPath does not exist |
SQUAD_TEAM_ROOT points to a non-existent path |
Set SQUAD_TEAM_ROOT to an initialized Squad team directory |
The system cannot find the file specified (Win32Exception) |
Copilot CLI not found | Same as first row above |
Build error: Package Squad.Agents.AI not found |
Sample uses a project reference; ensure you run from the repo root | Run dotnet build from the repository root or pass --project src/Squad.Agents.AI/samples/Squad.Agents.AI.Sample/ |
See also
- Root repo: https://github.com/bradygaster/squad
- Microsoft Agent Framework: https://github.com/microsoft/agents
- GitHub Copilot SDK authentication: https://github.com/github/copilot-sdk/blob/main/docs/auth/authenticate.md
- GitHub Copilot CLI: https://github.com/github/copilot-cli
- Changelog: https://github.com/bradygaster/squad/blob/main/CHANGELOG.md
License: MIT.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- GitHub.Copilot.SDK (>= 1.0.0)
- Microsoft.Agents.AI.GitHub.Copilot (>= 1.10.0-rc1)
- Microsoft.Extensions.AI (>= 10.6.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.8)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.8)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.8)
- Microsoft.Extensions.Options (>= 10.0.8)
-
net8.0
- GitHub.Copilot.SDK (>= 1.0.0)
- Microsoft.Agents.AI.GitHub.Copilot (>= 1.10.0-rc1)
- Microsoft.Extensions.AI (>= 10.6.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.8)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.8)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.8)
- Microsoft.Extensions.Options (>= 10.0.8)
-
net9.0
- GitHub.Copilot.SDK (>= 1.0.0)
- Microsoft.Agents.AI.GitHub.Copilot (>= 1.10.0-rc1)
- Microsoft.Extensions.AI (>= 10.6.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.8)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.8)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.8)
- Microsoft.Extensions.Options (>= 10.0.8)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.5.1-preview.8 | 38 | 6/11/2026 |
| 0.5.0-preview.7 | 36 | 6/11/2026 |
| 0.4.0-preview.6 | 34 | 6/11/2026 |
| 0.3.0-preview.5 | 44 | 6/11/2026 |
| 0.2.0-preview.4 | 41 | 6/10/2026 |
| 0.1.0-preview.3 | 39 | 6/10/2026 |
| 0.1.0-preview.2 | 36 | 6/9/2026 |