Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const (
ProviderAnthropic = config.ProviderAnthropic
ProviderOpenAI = config.ProviderOpenAI
ProviderCopilot = config.ProviderCopilot
ProviderBedrock = config.ProviderBedrock
)

type (
Expand All @@ -37,6 +38,7 @@ type (

AnthropicConfig = config.Anthropic
AWSBedrockConfig = config.AWSBedrock
BedrockConfig = config.Bedrock
OpenAIConfig = config.OpenAI
CopilotConfig = config.Copilot
)
Expand All @@ -57,6 +59,10 @@ func NewCopilotProvider(cfg config.Copilot) provider.Provider {
return provider.NewCopilot(cfg)
}

func NewBedrockProvider(cfg config.Bedrock) provider.Provider {
return provider.NewBedrock(cfg)
}

func NewMetrics(reg prometheus.Registerer) *metrics.Metrics {
return metrics.NewMetrics(reg)
}
Expand Down
12 changes: 12 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const (
ProviderAnthropic = "anthropic"
ProviderOpenAI = "openai"
ProviderCopilot = "copilot"
ProviderBedrock = "bedrock"
)

type Anthropic struct {
Expand Down Expand Up @@ -34,6 +35,17 @@ type AWSBedrock struct {
BaseURL string
}

// Bedrock is a standalone Bedrock provider configuration. It acts as a
// SigV4-signing reverse proxy, forwarding native Bedrock API requests
// to AWS and adding centralized AWS credentials.
type Bedrock struct {
// Name is the provider instance name. If empty, defaults to "bedrock".
Name string
APIDumpDir string
CircuitBreaker *CircuitBreaker
AWSBedrock // Region, AccessKey, AccessKeySecret, SessionToken, Model, SmallFastModel, BaseURL
}

type OpenAI struct {
// Name is the provider instance name. If empty, defaults to "openai".
Name string
Expand Down
88 changes: 88 additions & 0 deletions fixtures/bedrock/parse_eventstream.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//go:build ignore

// Usage: go run parse_eventstream.go <file.resp.bin>
//
// Decodes an AWS EventStream binary file and prints each frame's
// decoded JSON body. Use this to inspect captured Bedrock responses
// and verify fixture contents.
package main

import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"os"

"github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream"
"github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/eventstreamapi"
)

func main() {
if len(os.Args) < 2 {
fmt.Fprintf(os.Stderr, "usage: go run parse_eventstream.go <file.resp.bin>\n")
os.Exit(1)
}

data, err := os.ReadFile(os.Args[1])
if err != nil {
fmt.Fprintf(os.Stderr, "read file: %v\n", err)
os.Exit(1)
}

decoder := eventstream.NewDecoder()
reader := bytes.NewReader(data)
frameNum := 0

for {
msg, err := decoder.Decode(reader, nil)
if err != nil {
break
}
frameNum++

messageType := msg.Headers.Get(eventstreamapi.MessageTypeHeader)
eventType := msg.Headers.Get(eventstreamapi.EventTypeHeader)

fmt.Printf("=== Frame %d ===\n", frameNum)
fmt.Printf(" message-type: %s\n", headerStr(messageType))
fmt.Printf(" event-type: %s\n", headerStr(eventType))

if headerStr(eventType) != "chunk" {
fmt.Printf(" payload: %s\n\n", string(msg.Payload))
continue
}

var chunk struct {
Bytes string `json:"bytes"`
}
if err := json.Unmarshal(msg.Payload, &chunk); err != nil {
fmt.Printf(" unmarshal error: %v\n\n", err)
continue
}

decoded, err := base64.StdEncoding.DecodeString(chunk.Bytes)
if err != nil {
fmt.Printf(" base64 decode error: %v\n\n", err)
continue
}

var pretty json.RawMessage
if err := json.Unmarshal(decoded, &pretty); err != nil {
fmt.Printf(" json: %s\n\n", string(decoded))
continue
}

indented, _ := json.MarshalIndent(pretty, " ", " ")
fmt.Printf(" body:\n %s\n\n", string(indented))
}

fmt.Printf("Total frames: %d\n", frameNum)
}

func headerStr(h eventstream.Value) string {
if h == nil {
return "<nil>"
}
return h.String()
}
10 changes: 10 additions & 0 deletions fixtures/bedrock/simple.req.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 50,
"messages": [
{
"role": "user",
"content": "how many angels can dance on the head of a pin"
}
]
}
Binary file added fixtures/bedrock/simple.resp.bin
Binary file not shown.
Loading
Loading