From f83daa9581ad4039d520163900431c0dd4e787ad Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2026 15:57:05 +0000 Subject: [PATCH 1/3] feat: add AWS PRM user-agent attribution for Bedrock calls --- intercept/messages/base.go | 1 + 1 file changed, 1 insertion(+) diff --git a/intercept/messages/base.go b/intercept/messages/base.go index 09372ec7..39de38c5 100644 --- a/intercept/messages/base.go +++ b/intercept/messages/base.go @@ -285,6 +285,7 @@ func (i *interceptionBase) withAWSBedrockOptions(ctx context.Context, cfg *aibco opts := []func(*config.LoadOptions) error{ config.WithRegion(cfg.Region), + config.WithAppID("APN_1.1/pc_cdfmjwn8i6u8l9fwz8h82e4w3$"), config.WithCredentialsProvider( credentials.NewStaticCredentialsProvider( cfg.AccessKey, From 262727ee9998a73f20111f502fdc918af7047f5b Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Tue, 24 Mar 2026 20:15:27 +0000 Subject: [PATCH 2/3] fix: use middleware to append APN user-agent instead of config.WithAppID config.WithAppID has no effect because the Anthropic SDK sets User-Agent directly on the request, bypassing the AWS SDK user-agent builder. Replace it with an option.WithMiddleware that appends the APN token to the existing User-Agent header. Confirmed working via CloudTrail: "userAgent": "Anthropic/Go 1.19.0 sdk-ua-app-id/APN_1.1%2Fpc_cdfmjwn8i6u8l9fwz8h82e4w3%24" --- intercept/messages/base.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/intercept/messages/base.go b/intercept/messages/base.go index 39de38c5..be87f641 100644 --- a/intercept/messages/base.go +++ b/intercept/messages/base.go @@ -285,7 +285,6 @@ func (i *interceptionBase) withAWSBedrockOptions(ctx context.Context, cfg *aibco opts := []func(*config.LoadOptions) error{ config.WithRegion(cfg.Region), - config.WithAppID("APN_1.1/pc_cdfmjwn8i6u8l9fwz8h82e4w3$"), config.WithCredentialsProvider( credentials.NewStaticCredentialsProvider( cfg.AccessKey, @@ -301,6 +300,12 @@ func (i *interceptionBase) withAWSBedrockOptions(ctx context.Context, cfg *aibco } var out []option.RequestOption + out = append(out, option.WithMiddleware(func(req *http.Request, next option.MiddlewareNext) (*http.Response, error) { + if ua := req.Header.Get("User-Agent"); ua != "" { + req.Header.Set("User-Agent", ua+" sdk-ua-app-id/APN_1.1%2Fpc_cdfmjwn8i6u8l9fwz8h82e4w3%24") + } + return next(req) + })) out = append(out, bedrock.WithConfig(awsCfg)) // If a custom base URL is set, override the default endpoint constructed by the bedrock middleware. From 3e06c653cd454d9b57f01f7d4b33ae9b15ea80c1 Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 17:51:35 +0000 Subject: [PATCH 3/3] test: verify PRM user-agent attribution on Bedrock requests Adds two integration test assertions: - Positive: Bedrock requests include the PRM sdk-ua-app-id in User-Agent - Negative: Non-Bedrock Anthropic requests do not include PRM attribution --- internal/integrationtest/bridge_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/internal/integrationtest/bridge_test.go b/internal/integrationtest/bridge_test.go index a2a746e3..7a92edfa 100644 --- a/internal/integrationtest/bridge_test.go +++ b/internal/integrationtest/bridge_test.go @@ -118,6 +118,13 @@ func TestAnthropicMessages(t *testing.T) { require.Len(t, promptUsages, 1) assert.Equal(t, "read the foo file", promptUsages[0].Prompt) + // Verify PRM attribution is NOT present on non-Bedrock Anthropic requests. + received := upstream.receivedRequests() + require.Len(t, received, 1) + ua := received[0].Header.Get("User-Agent") + assert.NotContains(t, ua, "sdk-ua-app-id", + "PRM attribution should not be present on non-Bedrock requests") + bridgeServer.Recorder.VerifyAllInterceptionsEnded(t) }) } @@ -308,6 +315,11 @@ func TestAWSBedrockIntegration(t *testing.T) { require.False(t, gjson.GetBytes(received[0].Body, "model").Exists(), "model should be stripped from body") require.False(t, gjson.GetBytes(received[0].Body, "stream").Exists(), "stream should be stripped from body") + // Verify PRM attribution is appended to the User-Agent header. + ua := received[0].Header.Get("User-Agent") + require.Contains(t, ua, "sdk-ua-app-id/APN_1.1%2Fpc_cdfmjwn8i6u8l9fwz8h82e4w3%24", + "expected AWS PRM attribution in User-Agent header") + interceptions := bridgeServer.Recorder.RecordedInterceptions() require.Len(t, interceptions, 1) require.Equal(t, interceptions[0].Model, bedrockCfg.Model)