From approved case inputs to a first turn
Bring a model.
Start with a business case.
Begin with a credential-free inspection. Then use fictional RFP and product-capability text for a read-only research request. This is a small integration check on the way to an RFP response workbench inside your application, not a coding-assistant workflow.
The package is not on NuGet.org. HveSquad.AgentFramework version 0.1.0-preview.1 is an unpublished preview. Use the project-reference path below, or pack it into a local feed. No separate MCP service is required. Maintainers follow the package publishing instructions before any public installation claim.
What you need
| Dependency | When and why |
|---|---|
| .NET 10 SDK | Build and run the library and sample. The integration uses Microsoft.Agents.AI 1.17.0 and Microsoft.Extensions.AI 10.8.3. |
| Git + APM CLI | On PATH for first release acquisition. Compatibility CI exercises APM 0.18.0. Install using the official APM instructions. |
| GitHub / dependency access | Resolve a published release and install its full pinned dependency graph. A source clone alone is not the installed skill tree. |
| A dedicated case directory | An existing writable directory for approved input text, output artifacts, and native state. ProjectPath is its API name; a business case needs no code checkout or Git repository. Use a fresh isolated directory without existing Copilot squad state. |
| A model binding | Only live execution needs IChatClient and a capable model. The sample uses the official OpenAI adapter. A local compatible model can work if your provider supports the required tool-calling behavior. |
Commands below use PowerShell and Windows paths. Change C:\Solutions, C:\projects, and C:\app-data to your own authorized locations. The integration source checkout and the business case directory are different things: Git/APM acquire released artifacts; the case directory persists application work.
01. Inspect a published release
Clone the integration repository if you do not have it yet, then build it. Inspection makes no paid model calls, but the release commands require network and APM access.
New-Item -ItemType Directory -Force C:\Solutions | Out-Null
Set-Location C:\Solutions
git clone https://github.com/Peter-N91/hve-squad-maf.git
Set-Location C:\Solutions\hve-squad-maf
dotnet --version
git --version
apm --version
dotnet build HveSquad.AgentFramework.slnx
dotnet run --project samples\HveSquad.AgentFramework.Sample -- --release v0.16.2
dotnet run --project samples\HveSquad.AgentFramework.Sample -- --latestExpect the release tag, commit, artifact counts, available profiles and packs, and a staged workflow description. For v0.16.2, the exercised commit is a941195c36dfb6181453f51ec4638b085ca3b3ad. Warnings about opt-in external delegates do not imply those capabilities are installed.
With no arguments, the inspector searches upward for installed project artifacts. Positional directory arguments inspect explicit artifact roots. Neither path is the live runtime's default release acquisition.
02. Run the existing console sample
Provision OPENAI_API_KEY and OPENAI_MODEL in the process environment through your secret manager or secure local configuration. Do not put credentials in source, command history, or run JSON. The sample requires both variables.
OPENAI_ENDPOINT is optional and must be an absolute HTTP or HTTPS URI. Use HTTPS for remote providers; plain HTTP is only appropriate for an explicitly trusted local endpoint. OpenAI-compatible providers, including a correctly configured Azure OpenAI v1 endpoint, must support the selected model and tool calls.
Set-Location C:\Solutions\hve-squad-maf
New-Item -ItemType Directory -Force C:\app-data\bid-cases\demo\inputs | Out-Null
Set-Content -LiteralPath C:\app-data\bid-cases\demo\inputs\rfp.txt -Encoding utf8 `
-Value "RFP-01 (fictional): Which input formats does the knowledge-search product support?"
Set-Content -LiteralPath C:\app-data\bid-cases\demo\inputs\approved-capabilities.txt -Encoding utf8 `
-Value "CAP-01 (fictional approved evidence): Knowledge search accepts plain text. No other formats are evidenced."
dotnet run --project samples\HveSquad.AgentFramework.Sample -- `
--run "Research the question in inputs\rfp.txt using inputs\approved-capabilities.txt. Cite source identifiers and report gaps. Stop after research; do not change inputs or send anything externally." `
--project C:\app-data\bid-cases\demo `
--version v0.16.2 `
--profile fullThese fixture files contain no real customer or product data. Use a fresh demo directory; the commands replace the two named files. Review the complete initialization and routing proposals, including the research-only scope. Only enter yes when you approve the proposal actually shown. Answer any questions, or stop with Ctrl+C. A focused research run writes research evidence, not a completed proposal response.
What the sample can actually do: read contained case files and write scoped methodology artifacts. It also registers a contained write_project_file tool for the developer role after explicit approval; that optional source-writing demonstration is not needed for this request or the application's business proposition. It has no shell, build, test, web-search, or deployment executor. The library binding below registers no host tools.
Configuration-file alternative
Save this content as run.json in the integration repository. These are sample CLI fields, not the complete runtime configuration schema.
{
"request": "Research the question in inputs\\rfp.txt using inputs\\approved-capabilities.txt. Cite source identifiers and report gaps. Stop after research; do not change inputs or send anything externally.",
"project": "C:\\app-data\\bid-cases\\demo",
"version": "v0.16.2",
"profile": "full"
}dotnet run --project samples\HveSquad.AgentFramework.Sample -- --config run.jsonCLI flags are --run, --project, --version, and --profile. --config takes one file and is not combined with these flags. Unknown JSON members and invalid or duplicate flags are rejected. Successful delivery, research, plan, or review returns exit code 0; other outcomes return 1, invalid arguments return 2, and cancellation returns 130.
03. Add a project reference
This is the simplest integration path before publication. It builds the library directly from your checkout. The OpenAI adapter below is needed only for the standalone provider example, not for callers that already have an IChatClient.
dotnet new console --framework net10.0 --output C:\projects\SquadHost
dotnet add C:\projects\SquadHost\SquadHost.csproj reference `
C:\Solutions\hve-squad-maf\src\HveSquad.AgentFramework\HveSquad.AgentFramework.csproj
dotnet add C:\projects\SquadHost\SquadHost.csproj package `
Microsoft.Extensions.AI.OpenAI --version 10.8.304. Bind your IChatClient
Add the following as SquadEntry.cs in the consumer application. The application supplies the client and the authorized case directory prepared above; console callbacks explicitly approve proposals and answer questions. This first request only researches capability evidence. For the complete app-owned draft job, including typed output selection and UI callbacks, use BidDraftService.DraftAsync.
using System.Text.Json;
using HveSquad.AgentFramework.Runtime;
using Microsoft.Extensions.AI;
internal static class SquadEntry
{
public static async Task<SquadRunResult> ResearchAsync(
IChatClient chatClient,
string caseDirectory,
CancellationToken cancellationToken = default)
{
var options = new SquadRuntimeOptions
{
ProjectPath = caseDirectory,
Profile = "full",
Version = "v0.16.2",
InputPaths = [@"inputs\rfp.txt", @"inputs\approved-capabilities.txt"],
Tools = [],
ApprovalChannel = "in-chat",
ApproveAsync = async (proposal, token) =>
{
Console.WriteLine(JsonSerializer.Serialize(proposal));
Console.Write("Approve this exact proposal? Type yes: ");
return string.Equals(
await Console.In.ReadLineAsync(token),
"yes", StringComparison.OrdinalIgnoreCase);
},
AskAsync = async (question, token) =>
{
Console.WriteLine($"{question.Role}: {question.Question}");
return await Console.In.ReadLineAsync(token);
}
};
using var squad = await SquadRuntime.CreateAsync(
chatClient, options, cancellationToken: cancellationToken);
return await squad.RunAsync(
"Research the supplied RFP question using only approved capability evidence. " +
"Cite source identifiers and report gaps. Stop after research; " +
"do not change inputs or send anything externally.",
cancellationToken);
}
}If you already have a configured client, call SquadEntry.ResearchAsync(chatClient, caseDirectory, cancellationToken) from your application. The runtime does not dispose that client. InputPaths is not a read allowlist: native reads can access other contained files, so provision only authorized case material. Tools = [] removes custom host capabilities, not native reading, artifact writing, or state persistence.
The full roster also has the technical-writer and intake seats needed by the later delivery example. Research-only does not run intake. A delivery/plan request with these inputs does, and the released PRD Quality Reviewer may not fit arbitrary RFP material; handle an explicit blocker rather than promise generic document validation.
Standalone provider binding
For the new console project above, replace Program.cs with this complete example. It reads an already provisioned environment and contains no credential literals.
using System.ClientModel;
using Microsoft.Extensions.AI;
using OpenAI;
var key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")
?? throw new InvalidOperationException("Provision OPENAI_API_KEY securely.");
var model = Environment.GetEnvironmentVariable("OPENAI_MODEL")
?? throw new InvalidOperationException("Set OPENAI_MODEL for your provider.");
var clientOptions = new OpenAIClientOptions();
var endpoint = Environment.GetEnvironmentVariable("OPENAI_ENDPOINT");
if (!string.IsNullOrWhiteSpace(endpoint))
clientOptions.Endpoint = new Uri(endpoint, UriKind.Absolute);
var provider = new OpenAIClient(new ApiKeyCredential(key), clientOptions);
using IChatClient chatClient = provider.GetChatClient(model).AsIChatClient();
using var cancellation = new CancellationTokenSource();
Console.CancelKeyPress += (_, e) =>
{
e.Cancel = true;
cancellation.Cancel();
};
try
{
var result = await SquadEntry.ResearchAsync(
chatClient, @"C:\app-data\bid-cases\demo", cancellation.Token);
Console.WriteLine($"{result.Status}: {result.ResponseText}");
Console.WriteLine($"Verified dispatches: {result.Evidence.Count}");
}
catch (OperationCanceledException)
{
Console.WriteLine("Cancelled. No completion is claimed.");
}dotnet run --project C:\projects\SquadHost\SquadHost.csprojResearchCompleted means research completed, not implementation. Handle ApprovalRequired, InputRequired, and partial evidence as first-class outcomes. Configuration, acquisition, state validation, and lock errors can throw before a run result exists. See the complete result contract.
Alternative: consume a local package
Choose this instead of the project reference. Do not add both references to one consumer. These commands pack the current source and restore from the local feed plus NuGet.org for public dependencies. Packaging is not publishing; see the maintainer publishing procedure.
Set-Location C:\Solutions\hve-squad-maf
dotnet build HveSquad.AgentFramework.slnx --configuration Release
dotnet pack src\HveSquad.AgentFramework --configuration Release --output artifacts
dotnet new console --framework net10.0 --output C:\projects\SquadPackageHost
dotnet add C:\projects\SquadPackageHost\SquadPackageHost.csproj package `
HveSquad.AgentFramework --version 0.1.0-preview.1 --no-restore
dotnet add C:\projects\SquadPackageHost\SquadPackageHost.csproj package `
Microsoft.Extensions.AI.OpenAI --version 10.8.3 --no-restore
dotnet restore C:\projects\SquadPackageHost\SquadPackageHost.csproj `
--source C:\Solutions\hve-squad-maf\artifacts `
--source https://api.nuget.org/v3/index.jsonAdd the same SquadEntry.cs and Program.cs from above, then run dotnet run --project C:\projects\SquadPackageHost --no-restore. For ongoing use, add the local feed to the consumer's NuGet.Config; preserve any organization package-source mapping policy. The generated package is artifacts\HveSquad.AgentFramework.0.1.0-preview.1.nupkg, not a published download.
After publication only
The following public-feed installation is NOT available until a maintainer publishes this version. It shows the intended consumer command, not a working public installation today.
dotnet add package HveSquad.AgentFramework --version 0.1.0-preview.1Use dependency injection in an existing host
AddHveSquad returns the service collection and registers a transient SquadRuntimeFactory. It is an async factory pattern, not a synchronously constructed runtime. Acquisition happens in CreateAsync.
{
"HveSquad": {
"ProjectPath": "C:\\app-data\\bid-cases\\demo",
"Profile": "full",
"Version": "v0.16.2",
"Mode": "interactive",
"Packs": [],
"InputPaths": ["inputs\\rfp.txt", "inputs\\approved-capabilities.txt"],
"MaxDispatches": 32,
"MaxModelCalls": 64,
"RunTimeout": "00:30:00"
}
}The following belongs in your existing host composition root. services, configuration, chatClient, and serviceProvider are supplied by that application. Host callbacks use the same signatures as the direct example.
using HveSquad.AgentFramework.Hosting;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
services.AddSingleton<IChatClient>(chatClient);
services.AddHveSquad(
configuration.GetSection("HveSquad"),
configureHost: options =>
{
options.ApproveAsync = ApproveInYourApplicationAsync;
options.AskAsync = AskInYourApplicationAsync;
});
// Later, resolve from your application's built service provider.
var factory = serviceProvider.GetRequiredService<SquadRuntimeFactory>();
using var squad = await factory.CreateAsync(cancellationToken);
var result = await squad.RunAsync(request, cancellationToken);Each factory call creates an independently owned runtime. This configuration describes one demo case, not a multi-tenant directory shared by all requests. The app must authorize and select a separate persistent case directory for each business case, and its queue must enforce one active run per case. Do not dispose a runtime while its run is active.
Register tools, filters, logging, model selection, and callbacks in code, never in JSON. For a hosted UI, implement real human interaction rather than unconditional approval. Callbacks await answers during RunTimeout; there is no durable approval suspension or automatic background-job resume. The app owns document ingestion and rights, approval transport, job status, and secure result delivery. See the application boundary.