Universal.Operative.Sdk.Realtime.AwsBedrock
1.0.0
dotnet add package Universal.Operative.Sdk.Realtime.AwsBedrock --version 1.0.0
NuGet\Install-Package Universal.Operative.Sdk.Realtime.AwsBedrock -Version 1.0.0
<PackageReference Include="Universal.Operative.Sdk.Realtime.AwsBedrock" Version="1.0.0" />
<PackageVersion Include="Universal.Operative.Sdk.Realtime.AwsBedrock" Version="1.0.0" />
<PackageReference Include="Universal.Operative.Sdk.Realtime.AwsBedrock" />
paket add Universal.Operative.Sdk.Realtime.AwsBedrock --version 1.0.0
#r "nuget: Universal.Operative.Sdk.Realtime.AwsBedrock, 1.0.0"
#:package Universal.Operative.Sdk.Realtime.AwsBedrock@1.0.0
#addin nuget:?package=Universal.Operative.Sdk.Realtime.AwsBedrock&version=1.0.0
#tool nuget:?package=Universal.Operative.Sdk.Realtime.AwsBedrock&version=1.0.0
About
Universal.Operative.Sdk.Realtime.AwsBedrock adapts the Amazon Bedrock Nova Sonic bidirectional streaming API to Universal.Operative.Sdk.Realtime's provider-neutral IModel/IRealtimeSession/SessionEvent model.
Unlike the OpenAI and Gemini adapters, Bedrock's InvokeModelWithBidirectionalStreamAsync is a generic byte-stream API with no Nova-Sonic-specific vendor types -- every event (sessionStart, promptStart, contentStart, audioInput, toolResult, ...) is JSON this adapter constructs and parses directly, grounded in AWS's own input/output event documentation.
How to Use
Installation
dotnet add package Universal.Operative.Sdk
dotnet add package Universal.Operative.Sdk.Realtime
dotnet add package Universal.Operative.Sdk.Realtime.AwsBedrock
Quick start
using Universal.Operative.Sdk.Realtime;
using Universal.Operative.Sdk.Realtime.AwsBedrock;
// Bare model id -- Nova Sonic has neither a geo nor a global cross-region
// inference profile (per AWS's own model card), so a "us."/"eu." prefix is
// rejected, not just unnecessary. Region must be one Nova Sonic actually runs
// in: us-east-1, eu-north-1, or ap-northeast-1 as of this writing.
var model = new Model(new Model.Options
{
ModelId = "amazon.nova-sonic-v1:0",
Region = "us-east-1",
});
IRealtimeSession session = await model.ConnectAsync(new RealtimeSessionOptions
{
SystemPrompt = [new TextBlock("You are a helpful voice assistant.")],
Tools = [myTool],
});
await foreach (SessionOutputEvent e in session.Output)
{
switch (e)
{
case SessionReadyEvent: Console.WriteLine("connected"); break;
case TranscriptDeltaEvent t: Console.WriteLine($"{t.Role}: {t.Text}"); break;
case AudioOutputDeltaEvent a: /* play a.Audio (24kHz PCM16 by default) */ break;
case InterruptedEvent: /* stop playback immediately */ break;
}
}
await session.SendAsync(new AppendAudioInputEvent { Audio = micChunk });
await session.SendAsync(new CommitAudioInputEvent());
Fidelity notes
- Capabilities:
AudioInProcess | ToolCalling | Transcripts-- no resumption capability flags are set. Nova Sonic's connections are capped at 8 minutes; this adapter raises a syntheticSessionExpiringEventas that approaches, but does not (yet) implement the client-assisted splice/replay AWS's own samples use to hop to a fresh connection -- a caller must reconnect and replay its own history. - Interruption: Nova Sonic documents barge-in as a
contentEnd.stopReason == "INTERRUPTED"on the in-flight text content block -- mapped to aConfirmed-confidenceInterruptedEvent, not a heuristic. - Tool results: the full
ToolResultcontent is flattened into a single JSON object ({"result": "..."}or{"error": "..."}) sent as Nova Sonic'stoolResultevent content, mirroring the Gemini adapter. - Raw passthrough:
usageEvent, per-content-blockcontentStart/contentEndevents that aren't the interruption signal, and anything else not explicitly mapped arrive as aRawPassthroughEventrather than being dropped. - Tool choice:
RealtimeSessionOptions.ToolChoicethrowsNotSupportedException-- Nova Sonic'spromptStart.toolConfigurationonly ever carries a tools array; no mode/choice field exists anywhere in its schema. - Turn completion:
TurnCompletedEventis raised fromcontentEnd.stopReason == "END_TURN", not fromcompletionEndalone --completionEnddoesn't always arrive even after a full response has been delivered. - Continuous audio input: Nova Sonic closes the connection if no
audioInputevent arrives for about a minute while a prompt is open. While an audio content block is open,Sessionautomatically sends a short silence chunk during any gap to keep the connection alive; it does not open a block on its own. - Cross-modal text: sending text while no audio content block is open gets no response at all, matching AWS's documentation that cross-modal input requires an active streaming session. Even with an audio block open, a response to cross-modal text is occasionally absent.
| Product | Versions 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. |
-
net10.0
- AWSSDK.BedrockRuntime (>= 4.0.101.1)
- Universal.Operative.Sdk (>= 5.0.0)
- Universal.Operative.Sdk.Realtime (>= 1.0.0)
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 |
|---|---|---|
| 1.0.0 | 41 | 8/12/2026 |
Amazon Bedrock Nova Sonic adapter for Universal.Operative.Sdk.Realtime. Nova Sonic's bidirectional streaming API is a generic JSON-over-bytes channel with no strongly-typed vendor event model, so this adapter constructs and parses the documented event JSON directly. No session resumption (IRealtimeSession only, not IResumableSession) -- Nova Sonic's 8-minute connection cap surfaces as a synthetic SessionExpiringEvent. RealtimeSessionOptions.ToolChoice throws NotSupportedException, since Nova Sonic's promptStart schema has no tool-choice field.