Voxa.AspNetCore 0.7.2-alpha

This is a prerelease version of Voxa.AspNetCore.
dotnet add package Voxa.AspNetCore --version 0.7.2-alpha
                    
NuGet\Install-Package Voxa.AspNetCore -Version 0.7.2-alpha
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Voxa.AspNetCore" Version="0.7.2-alpha" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Voxa.AspNetCore" Version="0.7.2-alpha" />
                    
Directory.Packages.props
<PackageReference Include="Voxa.AspNetCore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Voxa.AspNetCore --version 0.7.2-alpha
                    
#r "nuget: Voxa.AspNetCore, 0.7.2-alpha"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Voxa.AspNetCore@0.7.2-alpha
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Voxa.AspNetCore&version=0.7.2-alpha&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Voxa.AspNetCore&version=0.7.2-alpha&prerelease
                    
Install as a Cake Tool

Voxa.AspNetCore

ASP.NET Core integration for Voxa. Provides AddVoxa service registration and MapVoxaVoice endpoint mapping. The Voxa meta-package references this and all built-in speech providers together — start there if you want zero boilerplate.

Zero-config setup (via the Voxa meta-package)

// Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddVoxa(builder.Configuration);  // meta-package 2-arg entry point
var app = builder.Build();
app.UseWebSockets();
app.MapVoxaVoice("/voice").UseDefaults();
app.Run();

Configure via appsettings.json:

{
  "Voxa": {
    "Profile": "LowLatency",
    "Stt": "OpenAI",
    "Tts": "OpenAI",
    "OpenAI": { "ApiKey": "sk-..." },
    "Agent": {
      "Provider": "OpenAI",
      "Model": "gpt-4o-mini",
      "Instructions": "You are a friendly voice assistant. Keep responses brief."
    }
  }
}

UseDefaults() composes: Silero VAD → STT → transcription filter → agent → sentence aggregator → TTS, with per-connection bounded conversation memory. A session envelope is pushed to the client at connection start, announcing the input/output sample rates so the client can configure its encoder/decoder without hardcoding.

Startup validation: VoxaDefaultsGuard is an IHostedService that fires at host startup (only when UseDefaults() was called). It verifies Voxa:Stt, Voxa:Tts, and that an agent is usable — and throws InvalidOperationException with a clear message listing the registered providers and what to set if anything is missing. When the agent will come from an IVoiceAgentFactory (rather than a DI-registered AIAgent/IChatClient), the guard calls the factory's Validate(VoxaAgentOptions) so an unsupported Voxa:Agent:Provider or a missing API key fails at startup, not on the first WebSocket request. Custom factory implementations can override Validate to participate; the default implementation reports no errors.

Sample-rate overrides: providers accept Voxa:<Section>:InputSampleRate / Voxa:<Section>:OutputSampleRate overrides (e.g. Voxa:OpenAI:OutputSampleRate). The session envelope and the VAD always use the effective rate — the override when present, the descriptor default otherwise — so clients and processors never disagree about the audio format.

À-la-carte setup (using Voxa.AspNetCore directly)

Install only the provider packages you want and register them explicitly:

builder.Services.AddVoxa(builder.Configuration, voxa => {
    voxa.AddProvider(OpenAISpeechDescriptors.Stt);
    voxa.AddProvider(ElevenLabsDescriptors.Tts);
    voxa.AddProvider(SileroVadDescriptors.Vad);
});

The configure callback is required (not optional) — this prevents overload-resolution ambiguity with the meta-package's 2-arg overload. AddVoxa is idempotent: a second call merges its descriptors into the existing registry without re-registering infrastructure.

Route building

MapVoxaVoice(pattern) returns a VoxaVoiceRoute fluent builder:

// Fully managed pipeline
app.MapVoxaVoice("/voice").UseDefaults();

// Fully custom pipeline (2-arg overload; no HttpContext access needed)
app.MapVoxaVoice("/voice", pipeline => pipeline
    .UseSpeechToText(() => OpenAISpeech.StreamingTranscription(opts))
    .UseTranscriptionFilter()
    .UseMicrosoftAgent(myAgent)
    .UseSentenceAggregator()
    .UseTextToSpeech(() => OpenAISpeech.Synthesis(opts)));

// Fully custom pipeline with per-request context access (VoxaVoiceRoute.Use)
app.MapVoxaVoice("/voice").Use((ctx, pipeline) => pipeline
    .UseProcessor(ctx => new MyContextAwareProcessor(ctx.User)));

// Defaults + custom extension
app.MapVoxaVoice("/voice")
   .UseDefaults()
   .Use((ctx, pipeline) => pipeline.UseProcessor(() => new MyAuditProcessor()));

// Authorization
app.MapVoxaVoice("/voice").UseDefaults().RequireAuthorization("MyPolicy");

Use() is composable via += — multiple calls append rather than replace. An unmapped route (neither UseDefaults() nor Use() called) throws InvalidOperationException at request time rather than silently echoing audio.

Pipeline builder surface

pipeline.UseProcessor(ctx => new MyProcessor(ctx.RequestServices.GetRequiredService<...>()))
pipeline.UseProcessor(() => new MyStatelessProcessor())

// Speech vendor convenience
pipeline.UseSpeechToText(() => OpenAISpeech.StreamingTranscription(opts))
pipeline.UseTextToSpeech(() => OpenAISpeech.Synthesis(opts))
pipeline.UseSentenceAggregator()
pipeline.UseTranscriptionFilter()
pipeline.UseSilenceGate()

// Microsoft Agent Framework
pipeline.UseMicrosoftAgent(agent)
pipeline.UseMicrosoftAgent(agent, options => { /* configure */ })
pipeline.UseMicrosoftAgent(ctx => agentFactory(ctx), (ctx, options) => { /* configure */ })

// Endpoint metadata
route.RequireAuthorization("MyPolicy")
route.RequireCors("MyCorsPolicy")

// Hello envelope (typed; lands in HttpContext.Items[VoiceHello.HelloMetadataKey])
route.UseWebSocketHello<MyHello>((ws, ct) => ParseAsync(ws, ct))

// Custom frame types — emit your own JSON envelope without subclassing the sink
pipeline.UseCustomFrameSerializer(frame =>
    frame is MyFrame f ? JsonSerializer.Serialize(new { type = "myFrame", ... }) : null)

Advanced MAF integration

UseMicrosoftAgent(agent, options => {...}) exposes the full MicrosoftAgentVoiceOptions surface for hosts that need persisted history, frontend tools, post-turn audit, sanitized backend-tool progress, etc.:

pipeline.UseMicrosoftAgent(agent, options =>
{
    options.BuildMessages = (turn, ct) => LoadHistoryAsync(turn.UserText, ct);
    options.IsFrontendTool = name => myFrontendCatalog.Contains(name);
    options.BuildBackendToolStatus = name => name switch
    {
        "pf_get_spending_summary" => "Checking your spending...",
        _ => null,
    };
    options.OnTurnCompleted = (turn, summary, ct) => RecordAuditAsync(turn, summary, ct);
});

What happens per connection

  1. Pipeline is built (from UseDefaults() and/or Use() callbacks) before AcceptWebSocketAsync — config errors surface as HTTP 500, not a connected-then-aborted socket.
  2. WebSocket is accepted.
  3. PipelineRunner is started.
  4. SessionInfoFrame is injected — clients receive {"type":"session","v":1,"inputSampleRate":16000,"outputSampleRate":24000}.
  5. The runner drives the pipeline for the connection's lifetime; tears down cleanly on client disconnect or EndFrame.

See the main repo for the full options reference and the underlying AgentLoopProcessor design.

Product Compatible and additional computed target framework versions.
.NET 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Voxa.AspNetCore:

Package Downloads
Voxa

Batteries-included Voxa package. One package reference: AddVoxa(cfg) + MapVoxaVoice("/voice").UseDefaults() gives a working voice bot with STT, TTS, VAD, and an OpenAI chat agent — no knowledge of frames required.

Voxa.Transports.Twilio

Twilio Media Streams transport for the Voxa pipeline (VTL-001). MapVoxaTwilioVoice("/twilio") serves the TwiML webhook and accepts the media WebSocket, running a phone call through the SAME composed VAD→STT→agent→TTS pipeline as the native route — with barge-in. The wire is hand-rolled JSON over the shared Voxa.Transports.Telephony base (μ-law 8 kHz); no Twilio SDK, no WebRTC. Includes X-Twilio-Signature validation.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.7.2-alpha 99 7/10/2026
0.7.1-alpha 77 7/10/2026
0.7.0-alpha 77 7/10/2026
0.6.0-alpha 84 6/22/2026
0.5.0-alpha 76 6/13/2026
0.4.0-alpha 1,247 5/10/2026