Goa.Clients.Bedrock 0.9.0-preview

This is a prerelease version of Goa.Clients.Bedrock.
dotnet add package Goa.Clients.Bedrock --version 0.9.0-preview
                    
NuGet\Install-Package Goa.Clients.Bedrock -Version 0.9.0-preview
                    
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="Goa.Clients.Bedrock" Version="0.9.0-preview" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Goa.Clients.Bedrock" Version="0.9.0-preview" />
                    
Directory.Packages.props
<PackageReference Include="Goa.Clients.Bedrock" />
                    
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 Goa.Clients.Bedrock --version 0.9.0-preview
                    
#r "nuget: Goa.Clients.Bedrock, 0.9.0-preview"
                    
#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 Goa.Clients.Bedrock@0.9.0-preview
                    
#: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=Goa.Clients.Bedrock&version=0.9.0-preview&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Goa.Clients.Bedrock&version=0.9.0-preview&prerelease
                    
Install as a Cake Tool

Goa.Clients.Bedrock

A high-performance Amazon Bedrock client optimized for AWS Lambda functions. This package provides a lightweight, AOT-ready Bedrock client with strongly-typed operations and comprehensive error handling using the ErrorOr pattern.

Installation

dotnet add package Goa.Clients.Bedrock

Features

  • Native AOT support for faster Lambda cold starts
  • Converse API with fluent builder pattern
  • InvokeModel API for raw model access
  • ApplyGuardrail API for content moderation
  • CountTokens API for token estimation
  • Tool/function calling support
  • MCP (Model Context Protocol) tool adapter
  • Strongly-typed request/response objects
  • Built-in error handling with ErrorOr pattern

Basic Setup

using Goa.Clients.Bedrock;
using Microsoft.Extensions.DependencyInjection;

// Register Bedrock client with defaults
services.AddBedrock();

// Or with custom configuration
services.AddBedrock(config =>
{
    config.ServiceUrl = "https://bedrock-runtime.us-east-1.amazonaws.com";
    config.Region = "us-east-1";
    config.LogLevel = LogLevel.Debug;
});

// Or with simple parameters
services.AddBedrock(
    serviceUrl: null,
    region: "us-west-2",
    logLevel: LogLevel.Information
);

Usage

Simple Conversation

using Goa.Clients.Bedrock;
using Goa.Clients.Bedrock.Operations.Converse;

public class ChatService
{
    private readonly IBedrockClient _client;

    public ChatService(IBedrockClient client)
    {
        _client = client;
    }

    public async Task<string?> ChatAsync(string userMessage)
    {
        var request = new ConverseBuilder("anthropic.claude-3-sonnet-20240229-v1:0")
            .WithSystemPrompt("You are a helpful assistant.")
            .AddUserMessage(userMessage)
            .WithMaxTokens(1024)
            .Build();

        var result = await _client.ConverseAsync(request);

        if (result.IsError)
            return null;

        return result.Value.Output?.Message?.Content?.FirstOrDefault()?.Text;
    }
}

Builder Pattern with ConverseBuilder

The ConverseBuilder provides a fluent API for constructing conversation requests:

var request = new ConverseBuilder("anthropic.claude-3-sonnet-20240229-v1:0")
    .WithSystemPrompt("You are an expert programmer.")
    .AddUserMessage("What is dependency injection?")
    .AddAssistantMessage("Dependency injection is a design pattern...")
    .AddUserMessage("Can you show me an example?")
    .WithMaxTokens(2048)
    .WithTemperature(0.7f)
    .WithTopP(0.9f)
    .WithStopSequences("END", "STOP")
    .WithGuardrail("my-guardrail-id", "1")
    .WithPerformance(LatencyMode.Standard)
    .WithServiceTier(ServiceTier.Auto)
    .Build();

var result = await _client.ConverseAsync(request);

Tool/Function Calling

Define and use tools that the model can call:

using System.Text.Json;
using Goa.Clients.Bedrock.Operations.Converse;
using Goa.Clients.Bedrock.Models;

// Define the tool schema
var weatherSchema = JsonDocument.Parse("""
{
    "type": "object",
    "properties": {
        "location": {
            "type": "string",
            "description": "The city and state, e.g. San Francisco, CA"
        }
    },
    "required": ["location"]
}
""").RootElement;

// Build request with tool
var request = new ConverseBuilder("anthropic.claude-3-sonnet-20240229-v1:0")
    .AddUserMessage("What's the weather in Seattle?")
    .WithTool("get_weather", "Get the current weather for a location", weatherSchema)
    .WithToolChoice(new ToolChoice { Auto = new AutoToolChoice() })
    .WithMaxTokens(1024)
    .Build();

var result = await _client.ConverseAsync(request);

// Check if model wants to use a tool
if (result.Value.StopReason == StopReason.ToolUse)
{
    var toolUse = result.Value.Output?.Message?.Content?
        .FirstOrDefault(c => c.ToolUse != null)?.ToolUse;

    if (toolUse != null)
    {
        // Execute the tool and continue conversation
        var toolResult = ExecuteWeatherTool(toolUse.Input);

        // Add tool result and continue
        var followUp = new ConverseBuilder("anthropic.claude-3-sonnet-20240229-v1:0")
            .AddMessage(ConversationRole.User, result.Value.Output.Message.Content)
            .AddMessage(ConversationRole.User, new List<ContentBlock>
            {
                new() { ToolResult = new ToolResultBlock
                {
                    ToolUseId = toolUse.ToolUseId,
                    Status = "success",
                    Content = new List<ContentBlock> { new() { Text = toolResult } }
                }}
            })
            .Build();
    }
}

MCP Integration with McpToolAdapter

The McpToolAdapter bridges MCP tool definitions to Bedrock format:

using System.Text.Json;
using Goa.Clients.Bedrock.Mcp;
using Goa.Clients.Bedrock.Operations.Converse;

// Create the adapter
var adapter = new McpToolAdapter();

// Define MCP tools
var mcpTools = new List<McpToolDefinition>
{
    new()
    {
        Name = "calculator",
        Description = "Performs basic arithmetic operations",
        InputSchema = JsonDocument.Parse("""
        {
            "type": "object",
            "properties": {
                "operation": { "type": "string", "enum": ["add", "subtract", "multiply", "divide"] },
                "a": { "type": "number" },
                "b": { "type": "number" }
            },
            "required": ["operation", "a", "b"]
        }
        """).RootElement,
        Handler = async (input, ct) =>
        {
            var op = input.GetProperty("operation").GetString();
            var a = input.GetProperty("a").GetDouble();
            var b = input.GetProperty("b").GetDouble();

            var result = op switch
            {
                "add" => a + b,
                "subtract" => a - b,
                "multiply" => a * b,
                "divide" => a / b,
                _ => throw new ArgumentException($"Unknown operation: {op}")
            };

            return JsonDocument.Parse($"{{\"result\": {result}}}").RootElement;
        }
    }
};

// Convert to Bedrock tools
var bedrockTools = adapter.ToBedrockTools(mcpTools);

// Use in conversation
var request = new ConverseBuilder("anthropic.claude-3-sonnet-20240229-v1:0")
    .AddUserMessage("What is 42 multiplied by 17?")
    .WithMaxTokens(1024)
    .Build();

// Add tools to request
request.ToolConfig = new ToolConfiguration { Tools = bedrockTools.ToList() };

var result = await _client.ConverseAsync(request);

// Execute tool if requested
if (result.Value.StopReason == StopReason.ToolUse)
{
    var toolUse = result.Value.Output?.Message?.Content?
        .FirstOrDefault(c => c.ToolUse != null)?.ToolUse;

    if (toolUse != null)
    {
        var toolResult = await adapter.ExecuteToolAsync(toolUse);
        // Continue conversation with tool result...
    }
}

Raw Model Invocation

For direct model access with custom payloads:

using Goa.Clients.Bedrock.Operations.InvokeModel;

var request = new InvokeModelRequest
{
    ModelId = "anthropic.claude-3-sonnet-20240229-v1:0",
    Body = """
    {
        "anthropic_version": "bedrock-2023-05-31",
        "max_tokens": 1024,
        "messages": [
            {"role": "user", "content": "Hello!"}
        ]
    }
    """,
    ContentType = "application/json",
    Accept = "application/json"
};

var result = await _client.InvokeModelAsync(request);

if (!result.IsError)
{
    var responseBody = result.Value.Body;
    // Parse model-specific response format
}

Guardrails

Apply content moderation with Bedrock Guardrails:

using Goa.Clients.Bedrock.Operations.ApplyGuardrail;

var request = new ApplyGuardrailRequest
{
    GuardrailIdentifier = "my-guardrail-id",
    GuardrailVersion = "1",
    Source = "INPUT",
    Content = new List<GuardrailContentBlock>
    {
        new()
        {
            Text = new GuardrailTextBlock
            {
                Text = "User provided content to check..."
            }
        }
    }
};

var result = await _client.ApplyGuardrailAsync(request);

if (!result.IsError)
{
    var action = result.Value.Action; // NONE or GUARDRAIL_INTERVENED
}

Token Counting

Estimate token usage before making requests:

using Goa.Clients.Bedrock.Operations.CountTokens;
using Goa.Clients.Bedrock.Models;
using Goa.Clients.Bedrock.Enums;

var request = new CountTokensRequest
{
    ModelId = "anthropic.claude-3-sonnet-20240229-v1:0",
    Messages = new List<Message>
    {
        new()
        {
            Role = ConversationRole.User,
            Content = new List<ContentBlock>
            {
                new() { Text = "What is the meaning of life?" }
            }
        }
    },
    System = new List<SystemContentBlock>
    {
        new() { Text = "You are a philosophical assistant." }
    }
};

var result = await _client.CountTokensAsync(request);

if (!result.IsError)
{
    var inputTokens = result.Value.InputTokens;
}

Available Operations

Operation Method Description
Converse ConverseAsync Send conversation requests using the Converse API
InvokeModel InvokeModelAsync Invoke a model with raw JSON payload
ApplyGuardrail ApplyGuardrailAsync Apply content moderation guardrails
CountTokens CountTokensAsync Count tokens in a request

Error Handling

All operations return ErrorOr<T> results, providing comprehensive error handling:

var result = await _client.ConverseAsync(request);

if (result.IsError)
{
    foreach (var error in result.Errors)
    {
        Console.WriteLine($"Error: {error.Code} - {error.Description}");
    }
    return;
}

// Use successful result
var response = result.Value;
var text = response.Output?.Message?.Content?.FirstOrDefault()?.Text;

Documentation

For more information and examples, visit the main Goa documentation.

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 (1)

Showing the top 1 NuGet packages that depend on Goa.Clients.Bedrock:

Package Downloads
Goa.Clients.Bedrock.Conversation

Conversation store abstractions for Bedrock-based AI applications with source generator support for high-performance AWS Lambda functions

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.9.0-preview 286 6/18/2026
0.8.0-preview 402 3/17/2026
0.7.8-preview 112 3/3/2026
0.7.7-preview 72 3/3/2026
0.7.6-preview 72 3/3/2026
0.7.5-preview 79 3/2/2026
0.7.4-preview 74 3/1/2026
0.7.3-preview 79 2/28/2026
0.7.2-preview 81 2/23/2026
0.7.1-preview 108 1/26/2026
0.7.0-preview 82 1/26/2026