From 1c3dd0fca43fae0a5e3376a89d2b0aeae667992b Mon Sep 17 00:00:00 2001 From: Dmitry Ng <19asdek91@gmail.com> Date: Wed, 4 Mar 2026 01:08:38 +0300 Subject: [PATCH] feat: update AWS SDK dependencies and enhance caching support - Upgraded various AWS SDK dependencies in go.mod and go.sum files to their latest versions, improving compatibility and performance. - Introduced automatic caching support for specific Anthropic models, optimizing token usage and reducing costs. - Refactored message processing to include caching logic, ensuring seamless integration with existing functionalities. - Removed deprecated models from tests and updated test cases to validate new caching features and model support. --- .../bedrock-claude3-vision-example/go.mod | 31 +- .../bedrock-claude3-vision-example/go.sum | 62 +- examples/bedrock-provider-example/go.mod | 31 +- examples/bedrock-provider-example/go.sum | 62 +- go.mod | 35 +- go.sum | 36 + llms/bedrock/README.md | 813 +++++++-- llms/bedrock/bedrock_tool_integration_test.go | 200 --- llms/bedrock/bedrockllm.go | 174 +- llms/bedrock/bedrockllm_option.go | 96 +- llms/bedrock/bedrockllm_test.go | 1564 ++++++++++++++++- llms/bedrock/bedrockllm_unit_test.go | 267 +++ llms/bedrock/doc.go | 208 +++ .../internal/bedrockclient/bedrockclient.go | 11 + .../bedrockclient/bedrockclient_converse.go | 165 +- .../bedrockclient_integration_test.go | 14 +- .../bedrockclient/bedrockclient_test.go | 12 +- .../bedrockclient/provider_anthropic.go | 138 +- llms/bedrock/models_list.go | 105 +- ...stAmazonAutomaticCachingConverseAPI.httprr | 44 + ...TestAmazonAutomaticCachingLegacyAPI.httprr | 62 + ...ultiTurnCachingWithToolsConverseAPI.httprr | 58 + ...nMultiTurnCachingWithToolsLegacyAPI.httprr | 82 + ...mage.httprr => TestAmazonNovaImage.httprr} | 0 .../TestAmazonOutputConverseAPI.httprr | 434 +++-- .../TestAmazonReasoningConverseAPI.httprr | 148 +- ...AmazonReasoningStreamingConverseAPI.httprr | Bin 139502 -> 188456 bytes ...ialToolCallsWithThinkingConverseAPI.httprr | 30 + ...ngleToolCallWithThinkingConverseAPI.httprr | 30 + ...estAmazonStreamingOutputConverseAPI.httprr | Bin 300244 -> 416149 bytes ...TextResponseWithThinkingConverseAPI.httprr | 30 + ...onTextResponseWithThinkingLegacyAPI.httprr | 42 + ...nseWithThinkingStreamingConverseAPI.httprr | Bin 0 -> 11745 bytes .../TestAmazonToolCallingConverseAPI.httprr | 731 ++++++-- ...azonToolCallingStreamingConverseAPI.httprr | Bin 106180 -> 161032 bytes .../TestBedrockAnthropicToolCalling.httprr | 56 - ...ateClientWithBearerTokenCredentials.httprr | 15 + ...ateClientWithLongLeavingCredentials.httprr | 15 + 38 files changed, 4887 insertions(+), 914 deletions(-) delete mode 100644 llms/bedrock/bedrock_tool_integration_test.go create mode 100644 llms/bedrock/doc.go create mode 100644 llms/bedrock/testdata/TestAmazonAutomaticCachingConverseAPI.httprr create mode 100644 llms/bedrock/testdata/TestAmazonAutomaticCachingLegacyAPI.httprr create mode 100644 llms/bedrock/testdata/TestAmazonMultiTurnCachingWithToolsConverseAPI.httprr create mode 100644 llms/bedrock/testdata/TestAmazonMultiTurnCachingWithToolsLegacyAPI.httprr rename llms/bedrock/testdata/{TestAnthropicNovaImage.httprr => TestAmazonNovaImage.httprr} (100%) create mode 100644 llms/bedrock/testdata/TestAmazonSequentialToolCallsWithThinkingConverseAPI.httprr create mode 100644 llms/bedrock/testdata/TestAmazonSingleToolCallWithThinkingConverseAPI.httprr create mode 100644 llms/bedrock/testdata/TestAmazonTextResponseWithThinkingConverseAPI.httprr create mode 100644 llms/bedrock/testdata/TestAmazonTextResponseWithThinkingLegacyAPI.httprr create mode 100644 llms/bedrock/testdata/TestAmazonTextResponseWithThinkingStreamingConverseAPI.httprr delete mode 100644 llms/bedrock/testdata/TestBedrockAnthropicToolCalling.httprr create mode 100644 llms/bedrock/testdata/TestCreateClientWithBearerTokenCredentials.httprr create mode 100644 llms/bedrock/testdata/TestCreateClientWithLongLeavingCredentials.httprr diff --git a/examples/bedrock-claude3-vision-example/go.mod b/examples/bedrock-claude3-vision-example/go.mod index 5aa5397f..c12c7578 100644 --- a/examples/bedrock-claude3-vision-example/go.mod +++ b/examples/bedrock-claude3-vision-example/go.mod @@ -5,21 +5,22 @@ go 1.24.1 require github.com/vxcontrol/langchaingo v0.1.14-update.1 require ( - github.com/aws/aws-sdk-go-v2 v1.36.5 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 // indirect - github.com/aws/aws-sdk-go-v2/config v1.29.4 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.61 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 // indirect - github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.31.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.25.0 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.0 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.33.16 // indirect - github.com/aws/smithy-go v1.22.4 // indirect + github.com/aws/aws-sdk-go-v2 v1.41.2 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.5 // indirect + github.com/aws/aws-sdk-go-v2/config v1.32.10 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.19.10 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.18 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect + github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.50.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18 // indirect + github.com/aws/aws-sdk-go-v2/service/signin v1.0.6 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.11 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.15 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.41.7 // indirect + github.com/aws/smithy-go v1.24.1 // indirect github.com/dlclark/regexp2 v1.11.4 // indirect github.com/google/uuid v1.6.0 // indirect github.com/pkoukk/tiktoken-go v0.1.8 // indirect diff --git a/examples/bedrock-claude3-vision-example/go.sum b/examples/bedrock-claude3-vision-example/go.sum index add91b0a..d4d770a3 100644 --- a/examples/bedrock-claude3-vision-example/go.sum +++ b/examples/bedrock-claude3-vision-example/go.sum @@ -1,33 +1,35 @@ -github.com/aws/aws-sdk-go-v2 v1.36.5 h1:0OF9RiEMEdDdZEMqF9MRjevyxAQcf6gY+E7vwBILFj0= -github.com/aws/aws-sdk-go-v2 v1.36.5/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 h1:12SpdwU8Djs+YGklkinSSlcrPyj3H4VifVsKf78KbwA= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11/go.mod h1:dd+Lkp6YmMryke+qxW/VnKyhMBDTYP41Q2Bb+6gNZgY= -github.com/aws/aws-sdk-go-v2/config v1.29.4 h1:ObNqKsDYFGr2WxnoXKOhCvTlf3HhwtoGgc+KmZ4H5yg= -github.com/aws/aws-sdk-go-v2/config v1.29.4/go.mod h1:j2/AF7j/qxVmsNIChw1tWfsVKOayJoGRDjg1Tgq7NPk= -github.com/aws/aws-sdk-go-v2/credentials v1.17.61 h1:Hd/uX6Wo2iUW1JWII+rmyCD7MMhOe7ALwQXN6sKDd1o= -github.com/aws/aws-sdk-go-v2/credentials v1.17.61/go.mod h1:L7vaLkwHY1qgW0gG1zG0z/X0sQ5tpIY5iI13+j3qI80= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 h1:SsytQyTMHMDPspp+spo7XwXTP44aJZZAC7fBV2C5+5s= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36/go.mod h1:Q1lnJArKRXkenyog6+Y+zr7WDpk4e6XlR6gs20bbeNo= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 h1:i2vNHQiXUvKhs3quBR6aqlgJaiaexz/aNvdCktW/kAM= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36/go.mod h1:UdyGa7Q91id/sdyHPwth+043HhmP6yP9MBHgbZM0xo8= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 h1:Pg9URiobXy85kgFev3og2CuOZ8JZUBENF+dcgWBaYNk= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.31.0 h1:BbtWSM9690zWbSOuJjBm7t7SIqDWhHPhKKQLhqxL+ac= -github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.31.0/go.mod h1:XHkvWM72+3dn5ox7yG0/yBEnQ2y0SMLCaXE/t96rv0I= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY= -github.com/aws/aws-sdk-go-v2/service/sso v1.25.0 h1:2U9sF8nKy7UgyEeLiZTRg6ShBS22z8UnYpV6aRFL0is= -github.com/aws/aws-sdk-go-v2/service/sso v1.25.0/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.0 h1:wjAdc85cXdQR5uLx5FwWvGIHm4OPJhTyzUHU8craXtE= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.0/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.16 h1:BHEK2Q/7CMRMCb3nySi/w8UbIcPhKvYP5s1xf8/izn0= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.16/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4= -github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw= -github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/aws/aws-sdk-go-v2 v1.41.2 h1:LuT2rzqNQsauaGkPK/7813XxcZ3o3yePY0Iy891T2ls= +github.com/aws/aws-sdk-go-v2 v1.41.2/go.mod h1:IvvlAZQXvTXznUPfRVfryiG1fbzE2NGK6m9u39YQ+S4= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.5 h1:zWFmPmgw4sveAYi1mRqG+E/g0461cJ5M4bJ8/nc6d3Q= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.5/go.mod h1:nVUlMLVV8ycXSb7mSkcNu9e3v/1TJq2RTlrPwhYWr5c= +github.com/aws/aws-sdk-go-v2/config v1.32.10 h1:9DMthfO6XWZYLfzZglAgW5Fyou2nRI5CuV44sTedKBI= +github.com/aws/aws-sdk-go-v2/config v1.32.10/go.mod h1:2rUIOnA2JaiqYmSKYmRJlcMWy6qTj1vuRFscppSBMcw= +github.com/aws/aws-sdk-go-v2/credentials v1.19.10 h1:EEhmEUFCE1Yhl7vDhNOI5OCL/iKMdkkYFTRpZXNw7m8= +github.com/aws/aws-sdk-go-v2/credentials v1.19.10/go.mod h1:RnnlFCAlxQCkN2Q379B67USkBMu1PipEEiibzYN5UTE= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.18 h1:Ii4s+Sq3yDfaMLpjrJsqD6SmG/Wq/P5L/hw2qa78UAY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.18/go.mod h1:6x81qnY++ovptLE6nWQeWrpXxbnlIex+4H4eYYGcqfc= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18 h1:F43zk1vemYIqPAwhjTjYIz0irU2EY7sOb/F5eJ3HuyM= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18/go.mod h1:w1jdlZXrGKaJcNoL+Nnrj+k5wlpGXqnNrKoP22HvAug= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18 h1:xCeWVjj0ki0l3nruoyP2slHsGArMxeiiaoPN5QZH6YQ= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18/go.mod h1:r/eLGuGCBw6l36ZRWiw6PaZwPXb6YOj+i/7MizNl5/k= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc= +github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.50.0 h1:TDKR8ACRw7G+GFaQlhoy6biu+8q6ZtSddQCy9avMdMI= +github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.50.0/go.mod h1:XlhOh5Ax/lesqN4aZCUgj9vVJed5VoXYHHFYGAlJEwU= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5 h1:CeY9LUdur+Dxoeldqoun6y4WtJ3RQtzk0JMP2gfUay0= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5/go.mod h1:AZLZf2fMaahW5s/wMRciu1sYbdsikT/UHwbUjOdEVTc= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18 h1:LTRCYFlnnKFlKsyIQxKhJuDuA3ZkrDQMRYm6rXiHlLY= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18/go.mod h1:XhwkgGG6bHSd00nO/mexWTcTjgd6PjuvWQMqSn2UaEk= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.6 h1:MzORe+J94I+hYu2a6XmV5yC9huoTv8NRcCrUNedDypQ= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.6/go.mod h1:hXzcHLARD7GeWnifd8j9RWqtfIgxj4/cAtIVIK7hg8g= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.11 h1:7oGD8KPfBOJGXiCoRKrrrQkbvCp8N++u36hrLMPey6o= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.11/go.mod h1:0DO9B5EUJQlIDif+XJRWCljZRKsAFKh3gpFz7UnDtOo= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.15 h1:edCcNp9eGIUDUCrzoCu1jWAXLGFIizeqkdkKgRlJwWc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.15/go.mod h1:lyRQKED9xWfgkYC/wmmYfv7iVIM68Z5OQ88ZdcV1QbU= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.7 h1:NITQpgo9A5NrDZ57uOWj+abvXSb83BbyggcUBVksN7c= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.7/go.mod h1:sks5UWBhEuWYDPdwlnRFn1w7xWdH29Jcpe+/PJQefEs= +github.com/aws/smithy-go v1.24.1 h1:VbyeNfmYkWoxMVpGUAbQumkODcYmfMRfZ8yQiH30SK0= +github.com/aws/smithy-go v1.24.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo= diff --git a/examples/bedrock-provider-example/go.mod b/examples/bedrock-provider-example/go.mod index e9f71184..1f1dd5d7 100644 --- a/examples/bedrock-provider-example/go.mod +++ b/examples/bedrock-provider-example/go.mod @@ -5,21 +5,22 @@ go 1.24.1 require github.com/vxcontrol/langchaingo v0.1.14-update.1 require ( - github.com/aws/aws-sdk-go-v2 v1.36.5 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 // indirect - github.com/aws/aws-sdk-go-v2/config v1.29.4 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.61 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 // indirect - github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.31.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.25.0 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.0 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.33.16 // indirect - github.com/aws/smithy-go v1.22.4 // indirect + github.com/aws/aws-sdk-go-v2 v1.41.2 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.5 // indirect + github.com/aws/aws-sdk-go-v2/config v1.32.10 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.19.10 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.18 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect + github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.50.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18 // indirect + github.com/aws/aws-sdk-go-v2/service/signin v1.0.6 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.11 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.15 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.41.7 // indirect + github.com/aws/smithy-go v1.24.1 // indirect github.com/dlclark/regexp2 v1.11.4 // indirect github.com/google/uuid v1.6.0 // indirect github.com/pkoukk/tiktoken-go v0.1.8 // indirect diff --git a/examples/bedrock-provider-example/go.sum b/examples/bedrock-provider-example/go.sum index add91b0a..d4d770a3 100644 --- a/examples/bedrock-provider-example/go.sum +++ b/examples/bedrock-provider-example/go.sum @@ -1,33 +1,35 @@ -github.com/aws/aws-sdk-go-v2 v1.36.5 h1:0OF9RiEMEdDdZEMqF9MRjevyxAQcf6gY+E7vwBILFj0= -github.com/aws/aws-sdk-go-v2 v1.36.5/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 h1:12SpdwU8Djs+YGklkinSSlcrPyj3H4VifVsKf78KbwA= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11/go.mod h1:dd+Lkp6YmMryke+qxW/VnKyhMBDTYP41Q2Bb+6gNZgY= -github.com/aws/aws-sdk-go-v2/config v1.29.4 h1:ObNqKsDYFGr2WxnoXKOhCvTlf3HhwtoGgc+KmZ4H5yg= -github.com/aws/aws-sdk-go-v2/config v1.29.4/go.mod h1:j2/AF7j/qxVmsNIChw1tWfsVKOayJoGRDjg1Tgq7NPk= -github.com/aws/aws-sdk-go-v2/credentials v1.17.61 h1:Hd/uX6Wo2iUW1JWII+rmyCD7MMhOe7ALwQXN6sKDd1o= -github.com/aws/aws-sdk-go-v2/credentials v1.17.61/go.mod h1:L7vaLkwHY1qgW0gG1zG0z/X0sQ5tpIY5iI13+j3qI80= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 h1:SsytQyTMHMDPspp+spo7XwXTP44aJZZAC7fBV2C5+5s= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36/go.mod h1:Q1lnJArKRXkenyog6+Y+zr7WDpk4e6XlR6gs20bbeNo= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 h1:i2vNHQiXUvKhs3quBR6aqlgJaiaexz/aNvdCktW/kAM= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36/go.mod h1:UdyGa7Q91id/sdyHPwth+043HhmP6yP9MBHgbZM0xo8= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 h1:Pg9URiobXy85kgFev3og2CuOZ8JZUBENF+dcgWBaYNk= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.31.0 h1:BbtWSM9690zWbSOuJjBm7t7SIqDWhHPhKKQLhqxL+ac= -github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.31.0/go.mod h1:XHkvWM72+3dn5ox7yG0/yBEnQ2y0SMLCaXE/t96rv0I= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY= -github.com/aws/aws-sdk-go-v2/service/sso v1.25.0 h1:2U9sF8nKy7UgyEeLiZTRg6ShBS22z8UnYpV6aRFL0is= -github.com/aws/aws-sdk-go-v2/service/sso v1.25.0/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.0 h1:wjAdc85cXdQR5uLx5FwWvGIHm4OPJhTyzUHU8craXtE= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.0/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.16 h1:BHEK2Q/7CMRMCb3nySi/w8UbIcPhKvYP5s1xf8/izn0= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.16/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4= -github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw= -github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/aws/aws-sdk-go-v2 v1.41.2 h1:LuT2rzqNQsauaGkPK/7813XxcZ3o3yePY0Iy891T2ls= +github.com/aws/aws-sdk-go-v2 v1.41.2/go.mod h1:IvvlAZQXvTXznUPfRVfryiG1fbzE2NGK6m9u39YQ+S4= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.5 h1:zWFmPmgw4sveAYi1mRqG+E/g0461cJ5M4bJ8/nc6d3Q= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.5/go.mod h1:nVUlMLVV8ycXSb7mSkcNu9e3v/1TJq2RTlrPwhYWr5c= +github.com/aws/aws-sdk-go-v2/config v1.32.10 h1:9DMthfO6XWZYLfzZglAgW5Fyou2nRI5CuV44sTedKBI= +github.com/aws/aws-sdk-go-v2/config v1.32.10/go.mod h1:2rUIOnA2JaiqYmSKYmRJlcMWy6qTj1vuRFscppSBMcw= +github.com/aws/aws-sdk-go-v2/credentials v1.19.10 h1:EEhmEUFCE1Yhl7vDhNOI5OCL/iKMdkkYFTRpZXNw7m8= +github.com/aws/aws-sdk-go-v2/credentials v1.19.10/go.mod h1:RnnlFCAlxQCkN2Q379B67USkBMu1PipEEiibzYN5UTE= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.18 h1:Ii4s+Sq3yDfaMLpjrJsqD6SmG/Wq/P5L/hw2qa78UAY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.18/go.mod h1:6x81qnY++ovptLE6nWQeWrpXxbnlIex+4H4eYYGcqfc= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18 h1:F43zk1vemYIqPAwhjTjYIz0irU2EY7sOb/F5eJ3HuyM= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18/go.mod h1:w1jdlZXrGKaJcNoL+Nnrj+k5wlpGXqnNrKoP22HvAug= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18 h1:xCeWVjj0ki0l3nruoyP2slHsGArMxeiiaoPN5QZH6YQ= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18/go.mod h1:r/eLGuGCBw6l36ZRWiw6PaZwPXb6YOj+i/7MizNl5/k= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc= +github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.50.0 h1:TDKR8ACRw7G+GFaQlhoy6biu+8q6ZtSddQCy9avMdMI= +github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.50.0/go.mod h1:XlhOh5Ax/lesqN4aZCUgj9vVJed5VoXYHHFYGAlJEwU= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5 h1:CeY9LUdur+Dxoeldqoun6y4WtJ3RQtzk0JMP2gfUay0= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5/go.mod h1:AZLZf2fMaahW5s/wMRciu1sYbdsikT/UHwbUjOdEVTc= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18 h1:LTRCYFlnnKFlKsyIQxKhJuDuA3ZkrDQMRYm6rXiHlLY= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18/go.mod h1:XhwkgGG6bHSd00nO/mexWTcTjgd6PjuvWQMqSn2UaEk= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.6 h1:MzORe+J94I+hYu2a6XmV5yC9huoTv8NRcCrUNedDypQ= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.6/go.mod h1:hXzcHLARD7GeWnifd8j9RWqtfIgxj4/cAtIVIK7hg8g= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.11 h1:7oGD8KPfBOJGXiCoRKrrrQkbvCp8N++u36hrLMPey6o= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.11/go.mod h1:0DO9B5EUJQlIDif+XJRWCljZRKsAFKh3gpFz7UnDtOo= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.15 h1:edCcNp9eGIUDUCrzoCu1jWAXLGFIizeqkdkKgRlJwWc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.15/go.mod h1:lyRQKED9xWfgkYC/wmmYfv7iVIM68Z5OQ88ZdcV1QbU= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.7 h1:NITQpgo9A5NrDZ57uOWj+abvXSb83BbyggcUBVksN7c= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.7/go.mod h1:sks5UWBhEuWYDPdwlnRFn1w7xWdH29Jcpe+/PJQefEs= +github.com/aws/smithy-go v1.24.1 h1:VbyeNfmYkWoxMVpGUAbQumkODcYmfMRfZ8yQiH30SK0= +github.com/aws/smithy-go v1.24.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo= diff --git a/go.mod b/go.mod index 5504bbb3..73dfc353 100644 --- a/go.mod +++ b/go.mod @@ -56,13 +56,13 @@ require ( require ( cloud.google.com/go/aiplatform v1.85.0 cloud.google.com/go/vertexai v0.12.0 - github.com/aws/aws-sdk-go-v2 v1.36.5 - github.com/aws/aws-sdk-go-v2/config v1.29.4 - github.com/aws/aws-sdk-go-v2/service/bedrockagent v1.44.2 - github.com/aws/aws-sdk-go-v2/service/bedrockagentruntime v1.45.2 - github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.31.0 + github.com/aws/aws-sdk-go-v2 v1.41.2 + github.com/aws/aws-sdk-go-v2/config v1.32.10 + github.com/aws/aws-sdk-go-v2/service/bedrockagent v1.52.4 + github.com/aws/aws-sdk-go-v2/service/bedrockagentruntime v1.51.4 + github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.50.0 github.com/aws/aws-sdk-go-v2/service/s3 v1.78.2 - github.com/aws/smithy-go v1.22.4 + github.com/aws/smithy-go v1.24.1 golang.org/x/oauth2 v0.30.0 google.golang.org/api v0.238.0 google.golang.org/grpc v1.73.0 @@ -127,20 +127,21 @@ require ( cloud.google.com/go/compute/metadata v0.7.0 // indirect cloud.google.com/go/iam v1.5.2 // indirect cloud.google.com/go/longrunning v0.6.7 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.61 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.5 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.19.10 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.18 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5 // indirect github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.25.0 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.0 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.33.16 // indirect + github.com/aws/aws-sdk-go-v2/service/signin v1.0.6 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.11 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.15 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.41.7 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/google/s2a-go v0.1.9 // indirect diff --git a/go.sum b/go.sum index a4349368..9221c7a2 100644 --- a/go.sum +++ b/go.sum @@ -78,46 +78,82 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:W github.com/aws/aws-sdk-go v1.42.27/go.mod h1:OGr6lGMAKGlG9CVrYnWYDKIyb829c6EVBRjxqjmPepc= github.com/aws/aws-sdk-go-v2 v1.36.5 h1:0OF9RiEMEdDdZEMqF9MRjevyxAQcf6gY+E7vwBILFj0= github.com/aws/aws-sdk-go-v2 v1.36.5/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0= +github.com/aws/aws-sdk-go-v2 v1.41.2 h1:LuT2rzqNQsauaGkPK/7813XxcZ3o3yePY0Iy891T2ls= +github.com/aws/aws-sdk-go-v2 v1.41.2/go.mod h1:IvvlAZQXvTXznUPfRVfryiG1fbzE2NGK6m9u39YQ+S4= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 h1:12SpdwU8Djs+YGklkinSSlcrPyj3H4VifVsKf78KbwA= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11/go.mod h1:dd+Lkp6YmMryke+qxW/VnKyhMBDTYP41Q2Bb+6gNZgY= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.5 h1:zWFmPmgw4sveAYi1mRqG+E/g0461cJ5M4bJ8/nc6d3Q= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.5/go.mod h1:nVUlMLVV8ycXSb7mSkcNu9e3v/1TJq2RTlrPwhYWr5c= github.com/aws/aws-sdk-go-v2/config v1.29.4 h1:ObNqKsDYFGr2WxnoXKOhCvTlf3HhwtoGgc+KmZ4H5yg= github.com/aws/aws-sdk-go-v2/config v1.29.4/go.mod h1:j2/AF7j/qxVmsNIChw1tWfsVKOayJoGRDjg1Tgq7NPk= +github.com/aws/aws-sdk-go-v2/config v1.32.10 h1:9DMthfO6XWZYLfzZglAgW5Fyou2nRI5CuV44sTedKBI= +github.com/aws/aws-sdk-go-v2/config v1.32.10/go.mod h1:2rUIOnA2JaiqYmSKYmRJlcMWy6qTj1vuRFscppSBMcw= github.com/aws/aws-sdk-go-v2/credentials v1.17.61 h1:Hd/uX6Wo2iUW1JWII+rmyCD7MMhOe7ALwQXN6sKDd1o= github.com/aws/aws-sdk-go-v2/credentials v1.17.61/go.mod h1:L7vaLkwHY1qgW0gG1zG0z/X0sQ5tpIY5iI13+j3qI80= +github.com/aws/aws-sdk-go-v2/credentials v1.19.10 h1:EEhmEUFCE1Yhl7vDhNOI5OCL/iKMdkkYFTRpZXNw7m8= +github.com/aws/aws-sdk-go-v2/credentials v1.19.10/go.mod h1:RnnlFCAlxQCkN2Q379B67USkBMu1PipEEiibzYN5UTE= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.18 h1:Ii4s+Sq3yDfaMLpjrJsqD6SmG/Wq/P5L/hw2qa78UAY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.18/go.mod h1:6x81qnY++ovptLE6nWQeWrpXxbnlIex+4H4eYYGcqfc= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 h1:SsytQyTMHMDPspp+spo7XwXTP44aJZZAC7fBV2C5+5s= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36/go.mod h1:Q1lnJArKRXkenyog6+Y+zr7WDpk4e6XlR6gs20bbeNo= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18 h1:F43zk1vemYIqPAwhjTjYIz0irU2EY7sOb/F5eJ3HuyM= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18/go.mod h1:w1jdlZXrGKaJcNoL+Nnrj+k5wlpGXqnNrKoP22HvAug= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 h1:i2vNHQiXUvKhs3quBR6aqlgJaiaexz/aNvdCktW/kAM= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36/go.mod h1:UdyGa7Q91id/sdyHPwth+043HhmP6yP9MBHgbZM0xo8= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18 h1:xCeWVjj0ki0l3nruoyP2slHsGArMxeiiaoPN5QZH6YQ= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18/go.mod h1:r/eLGuGCBw6l36ZRWiw6PaZwPXb6YOj+i/7MizNl5/k= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 h1:Pg9URiobXy85kgFev3og2CuOZ8JZUBENF+dcgWBaYNk= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc= github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34 h1:ZNTqv4nIdE/DiBfUUfXcLZ/Spcuz+RjeziUtNJackkM= github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34/go.mod h1:zf7Vcd1ViW7cPqYWEHLHJkS50X0JS2IKz9Cgaj6ugrs= github.com/aws/aws-sdk-go-v2/service/bedrockagent v1.44.2 h1:gedxMyluRPy1ENN1dlOM7rK8Jek1wUvpA9z1Cz2s9N4= github.com/aws/aws-sdk-go-v2/service/bedrockagent v1.44.2/go.mod h1:8zZaELHNLx6LNNfMrzCtVVsOFFKP1905FKmsSFuhArM= +github.com/aws/aws-sdk-go-v2/service/bedrockagent v1.52.4 h1:i5WL+AoS/AhMscsWkH6akQfJIujCVjbWiBwW36XheVk= +github.com/aws/aws-sdk-go-v2/service/bedrockagent v1.52.4/go.mod h1:8bRM14bpnsP+IzbJMlW0245dDZb0BFBuy0POlammksA= github.com/aws/aws-sdk-go-v2/service/bedrockagentruntime v1.45.2 h1:bTaJuyz2i4XvlxMLBzXpdw9rjth9noDMKHB+lh/w3kk= github.com/aws/aws-sdk-go-v2/service/bedrockagentruntime v1.45.2/go.mod h1:J/EFJdG12RxcljWx7vSgfx7L5rVuKpZHmFYO/SXTxKc= +github.com/aws/aws-sdk-go-v2/service/bedrockagentruntime v1.51.4 h1:oeSeyDAM2KQxu9bylfGZIspla7yXa6/59+Br3IvgNvQ= +github.com/aws/aws-sdk-go-v2/service/bedrockagentruntime v1.51.4/go.mod h1:eF5QHzRKSt9xvuxNlXC4QgH2+9JUGUWb8KND0+f5f2E= github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.31.0 h1:BbtWSM9690zWbSOuJjBm7t7SIqDWhHPhKKQLhqxL+ac= github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.31.0/go.mod h1:XHkvWM72+3dn5ox7yG0/yBEnQ2y0SMLCaXE/t96rv0I= +github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.50.0 h1:TDKR8ACRw7G+GFaQlhoy6biu+8q6ZtSddQCy9avMdMI= +github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.50.0/go.mod h1:XlhOh5Ax/lesqN4aZCUgj9vVJed5VoXYHHFYGAlJEwU= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5 h1:CeY9LUdur+Dxoeldqoun6y4WtJ3RQtzk0JMP2gfUay0= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5/go.mod h1:AZLZf2fMaahW5s/wMRciu1sYbdsikT/UHwbUjOdEVTc= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.0 h1:lguz0bmOoGzozP9XfRJR1QIayEYo+2vP/No3OfLF0pU= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.0/go.mod h1:iu6FSzgt+M2/x3Dk8zhycdIcHjEFb36IS8HVUVFoMg0= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18 h1:LTRCYFlnnKFlKsyIQxKhJuDuA3ZkrDQMRYm6rXiHlLY= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18/go.mod h1:XhwkgGG6bHSd00nO/mexWTcTjgd6PjuvWQMqSn2UaEk= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15 h1:moLQUoVq91LiqT1nbvzDukyqAlCv89ZmwaHw/ZFlFZg= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15/go.mod h1:ZH34PJUc8ApjBIfgQCFvkWcUDBtl/WTD+uiYHjd8igA= github.com/aws/aws-sdk-go-v2/service/s3 v1.78.2 h1:jIiopHEV22b4yQP2q36Y0OmwLbsxNWdWwfZRR5QRRO4= github.com/aws/aws-sdk-go-v2/service/s3 v1.78.2/go.mod h1:U5SNqwhXB3Xe6F47kXvWihPl/ilGaEDe8HD/50Z9wxc= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.6 h1:MzORe+J94I+hYu2a6XmV5yC9huoTv8NRcCrUNedDypQ= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.6/go.mod h1:hXzcHLARD7GeWnifd8j9RWqtfIgxj4/cAtIVIK7hg8g= github.com/aws/aws-sdk-go-v2/service/sso v1.25.0 h1:2U9sF8nKy7UgyEeLiZTRg6ShBS22z8UnYpV6aRFL0is= github.com/aws/aws-sdk-go-v2/service/sso v1.25.0/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.11 h1:7oGD8KPfBOJGXiCoRKrrrQkbvCp8N++u36hrLMPey6o= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.11/go.mod h1:0DO9B5EUJQlIDif+XJRWCljZRKsAFKh3gpFz7UnDtOo= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.0 h1:wjAdc85cXdQR5uLx5FwWvGIHm4OPJhTyzUHU8craXtE= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.0/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.15 h1:edCcNp9eGIUDUCrzoCu1jWAXLGFIizeqkdkKgRlJwWc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.15/go.mod h1:lyRQKED9xWfgkYC/wmmYfv7iVIM68Z5OQ88ZdcV1QbU= github.com/aws/aws-sdk-go-v2/service/sts v1.33.16 h1:BHEK2Q/7CMRMCb3nySi/w8UbIcPhKvYP5s1xf8/izn0= github.com/aws/aws-sdk-go-v2/service/sts v1.33.16/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.7 h1:NITQpgo9A5NrDZ57uOWj+abvXSb83BbyggcUBVksN7c= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.7/go.mod h1:sks5UWBhEuWYDPdwlnRFn1w7xWdH29Jcpe+/PJQefEs= github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw= github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/aws/smithy-go v1.24.1 h1:VbyeNfmYkWoxMVpGUAbQumkODcYmfMRfZ8yQiH30SK0= +github.com/aws/smithy-go v1.24.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= diff --git a/llms/bedrock/README.md b/llms/bedrock/README.md index 6052d2b9..955cb8da 100644 --- a/llms/bedrock/README.md +++ b/llms/bedrock/README.md @@ -1,130 +1,725 @@ # AWS Bedrock LLM Provider -A comprehensive Go implementation for AWS Bedrock LLM models with support for multiple providers, streaming, tool calling, and multimodal capabilities. +Production-ready Go client for AWS Bedrock with support for 40+ models from 13 providers. -## Features +## Architecture Overview -### 🤖 **Extensive Model Support** -- **AI21**: Jamba 1.5 Large/Mini, Jamba Instruct -- **Amazon**: Nova Premier/Pro/Lite/Micro, Titan Text Premier -- **Anthropic**: Claude 4 Opus/Sonnet, Claude 3.7 Sonnet, Claude 3.5 Haiku/Sonnet -- **Cohere**: Command-R, Command-R+, Command Text/Light -- **Meta**: Llama 3.3 70B, Llama 3.1 8B, Llama 3 70B/8B -- **DeepSeek**: R1 - -### 🚀 **Advanced Capabilities** -- **Streaming**: Real-time response streaming for most models -- **Tool Calling**: Full function calling support with streaming -- **Reasoning**: Extended thinking support for Claude 3.7+ and Nova models -- **Multimodal**: Text, image, and document processing -- **Two APIs**: Modern Converse API + Legacy model-specific APIs - -## Quick Start - -```go -import "github.com/vxcontrol/langchaingo/llms/bedrock" - -// Basic usage -llm, err := bedrock.New() - -// With Converse API (recommended) -llm, err := bedrock.New( - bedrock.WithConverseAPI(), - bedrock.WithModel(bedrock.ModelAnthropicClaudeSonnet4), -) - -resp, err := llm.GenerateContent(ctx, messages) +```mermaid +graph TB + Client[Client Code] --> LLM[bedrock.LLM] + LLM --> Processing[Message Processing] + Processing --> Legacy[Legacy API Client] + Processing --> Converse[Converse API Client] + Legacy --> Anthropic[provider_anthropic.go] + Legacy --> Nova[provider_nova.go] + Legacy --> Others[provider_*.go] + Converse --> ConverseClient[ConverseClient] + Anthropic --> AWS[AWS SDK] + Nova --> AWS + Others --> AWS + ConverseClient --> AWS ``` -## Streaming +### Three-Layer Design + +**Why this architecture?** + +1. **Public API Layer** (`bedrockllm.go`) + - Single entry point: `bedrock.LLM` + - Hides complexity of dual API support + - Manages automatic caching logic + +2. **Message Processing Layer** (`processMessages()`) + - Converts `llms.MessageContent` → `bedrockclient.Message` + - Handles tool calls, reasoning, multimodal content + - Applies automatic cache control insertion + +3. **Internal Client Layer** (`internal/bedrockclient/`) + - Provider-specific implementations + - AWS SDK interaction + - Response parsing and streaming + +## Dual API Strategy + +### Why Two APIs? + +**Legacy API** (InvokeModel/InvokeModelWithResponseStream): +- Direct access to model-specific features +- Anthropic cache_control format support +- Broader model compatibility +- **Use when**: Model not supported by Converse API + +**Converse API** (Converse/ConverseStream): +- Unified interface across all models +- Native cachePoint support (AWS SDK types) +- Better error handling +- **Use when**: Building new applications (recommended) + +**Decision Point**: `useConverseAPI` flag in `LLM` struct + +```mermaid +flowchart LR + A[GenerateContent] --> B{useConverseAPI?} + B -->|true| C[generateContentWithConverseAPI] + B -->|false| D[generateContentWithLegacyAPI] + C --> E[ConverseClient] + D --> F[Provider Detection] + F --> G[createAnthropicCompletion] + F --> H[createNovaCompletion] + F --> I[create*Completion] +``` + +## Automatic Prompt Caching + +### How It Works + +**Challenge**: Anthropic's prompt caching requires manual cache control wrappers on client side. + +**Solution**: Automatic cache point insertion for Claude 4.x models. + +```mermaid +sequenceDiagram + participant Client + participant LLM + participant Processing + participant API + + Client->>LLM: GenerateContent(messages) + LLM->>LLM: supportsCaching(modelID)? + alt Claude 4.x model + LLM->>Processing: processMessagesWithCaching(autoCaching=true) + Processing->>Processing: applyAutomaticCaching() + Note over Processing: Add cache control to
last assistant/tool message + else Other model + LLM->>Processing: processMessagesWithCaching(autoCaching=false) + end + Processing->>API: Send with cache points + API-->>LLM: Response with cache metrics +``` + +**Implementation**: +- `supportsCaching()`: Pattern matching on model ID (`claude-opus-4`, `claude-sonnet-4`, `claude-haiku-4`) +- `applyAutomaticCaching()`: Adds `CacheControl{Type: "ephemeral", TTL: "5m"}` to last cacheable message (assistant or tool response) +- **Why last message?** Caches conversation history before new user input +- **TTL Options**: 5 minutes (default) or 1 hour (configurable via `EphemeralCacheOneHour()`) + +**Benefits**: +- 90% cost reduction on cached tokens +- Zero client code changes with automatic caching +- Works with both Legacy and Converse APIs +- Supports both manual (`WithCacheControl()`) and automatic (`WithAutomaticCaching()`) modes + +## Tool Calling Implementation + +### Provider-Specific Differences + +**Why different implementations?** + +Different providers use different formats for tool inputs in Converse API: + +| Provider | Input Format | Handled By | +|----------|-------------|------------| +| Anthropic | Native JSON objects | `map[string]any` direct | +| Nova | Native JSON objects | `map[string]any` direct | +| Cohere | Native JSON objects | `map[string]any` direct | +| GLM (Z.AI) | **String-based** | Not supported | + +**Problems with specific models**: +- **GLM (Z.AI)**: Backend expects tool input as string, not JSON object. This breaks Converse API spec. +- **AI21 Jamba**: Very hard rate limits prevent extensive testing of tool calling capabilities. +- **Meta Llama 3.3/3.1 70B/170B**: Unstable behavior when processing tool call results. +- **Mistral Magistral Small**: Tool calling not supported. +- **Moonshot Kimi K2-Thinking**: Unstable tool calling behavior in streaming mode. +- **Qwen3-VL**: Unstable tool calling in streaming mode. + +**Solution**: Models with backend issues or instability are excluded from tool calling tests. + +### convertToolCallInput() Logic + +**Why this function exists?** + +AWS SDK requires Smithy-compatible types for `document.NewLazyDocument()`. Standard Go types from `json.Unmarshal` aren't always compatible. ```go -streamingFunc := func(ctx context.Context, chunk streaming.Chunk) error { - fmt.Print(chunk.Content) - return nil +func convertToolCallInput(args any) (any, error) { + // 1. Check Smithy compatibility (structs with `document` tags) + if isSmithyValidObject(args) { + return args, nil + } + + // 2. Re-encode to normalize types for Smithy SDK + // Uses UseNumber() to preserve numeric precision during JSON roundtrip + jsonBytes := bytes.NewBuffer(nil) + json.NewEncoder(jsonBytes).Encode(args) + + decoder := json.NewDecoder(jsonBytes) + decoder.UseNumber() // Preserves large numbers accurately + + var jsonValue any + decoder.Decode(&jsonValue) + return jsonValue, nil +} +``` + +**Why UseNumber()?** + +Preserves numeric precision for large integers that might overflow float64. The `json.Number` type is properly handled by Smithy SDK's document encoding. + +### Document Unmarshal for Tool Responses + +**Why `UnmarshalSmithyDocument()`?** + +When extracting tool call from response, `block.Value.Input` is `document.LazyDocument`, not plain Go type: + +```go +// WRONG: json.Marshal on document - loses type info +argsJSON, _ := json.Marshal(block.Value.Input) + +// CORRECT: Unmarshal document first +var inputData any +block.Value.Input.UnmarshalSmithyDocument(&inputData) +argsJSON, _ := json.Marshal(inputData) +``` + +## Reasoning (Thinking) Support + +### Models Supporting Reasoning + +**Converse API**: +- Claude 4.6, 4.5, 4.1, 4.0 (Opus, Sonnet, Haiku) +- DeepSeek R1 +- OpenAI GPT OSS (120B, 20B) +- Moonshot Kimi K2-Thinking + +**Legacy API**: +- Claude 4.5, 4.1, 4.0 (Opus, Sonnet, Haiku) +- Claude 3.7 Sonnet + +**Why these models?** + +Extended thinking/reasoning capabilities are model-specific features. DeepSeek R1, OpenAI OSS, and Moonshot models provide reasoning through Converse API, while Anthropic models support both APIs. + +### Message Structure with Reasoning + +```mermaid +flowchart TB + A[AI Message with Reasoning] --> B{Legacy or Converse?} + B -->|Legacy API| C[Add thinking/redacted_thinking blocks
BEFORE text content] + B -->|Converse API| D[Add ReasoningContent blocks
with signature/redacted] + C --> E[anthropicTextGenerationInputContent array] + D --> F[types.ContentBlock array] +``` + +**Why order matters?** + +Anthropic API spec requires thinking blocks before text blocks in assistant messages. + +### Signature Preservation + +**Challenge**: Reasoning signatures must round-trip through conversations. + +**Solution**: Store in `reasoning.ContentReasoning.Signature` field, re-insert on next turn. + +```go +// Receive +choice.Reasoning.Signature = []byte(...) + +// Send back +llms.TextPartWithReasoning(content, reasoning) +``` + +## Message Processing Pipeline + +```mermaid +flowchart LR + A[llms.MessageContent] --> B[processMessagesWithCaching] + B --> C{autoCaching?} + C -->|true| D[applyAutomaticCaching] + C -->|false| E[bedrockclient.Message array] + D --> E + E --> F{API Type} + F -->|Legacy| G[Provider-specific format] + F -->|Converse| H[types.Message] + G --> I[InvokeModel] + H --> J[Converse] +``` + +### Key Transformations + +**llms.MessageContent → bedrockclient.Message**: +- Role mapping (System/Human/AI/Tool → provider format) +- Content type detection (Text/Binary/ToolCall/ToolResponse) +- Reasoning extraction and formatting +- Cache control attachment + +**bedrockclient.Message → AWS Request**: +- Legacy: JSON serialization with provider schemas +- Converse: AWS SDK types with document encoding + +## Adding New Models + +### Step-by-Step Process + +1. **Add Model Constant** (`models_list.go`) +```go +// Include: Description, max tokens, languages, use cases +ModelNewProvider = "provider.model-id" +``` + +2. **Update Provider Detection** (if new provider) +```go +// bedrockclient.go +case strings.Contains(modelID, "newprovider"): + return "newprovider" +``` + +3. **Implement Provider** (`internal/bedrockclient/provider_new.go`) +```go +func createNewProviderCompletion(ctx, client, modelID, messages, options) { + // 1. Convert messages to provider format + // 2. Build request payload + // 3. Call InvokeModel + // 4. Parse response + // 5. Return llms.ContentResponse +} +``` + +4. **Register in Switch** (`bedrockclient.go`) +```go +case "newprovider": + return createNewProviderCompletion(...) +``` + +5. **Add Tests** (`bedrockllm_test.go`) +- Add model to `TestAmazonOutputConverseAPI` models list (if Converse API supported) +- Add model to `TestAmazonOutputLegacyAPI` models list (Legacy API) +- Add model to `TestAmazonStreamingOutputConverseAPI` (if streaming supported) +- Add model to `TestAmazonStreamingOutputLegacyAPI` (if streaming with Legacy API supported) +- Add model to `TestAmazonToolCallingConverseAPI` (if tools supported) +- Add model to `TestAmazonToolCallingLegacyAPI` (if tools with Legacy API supported) +- Add model to `TestAmazonReasoningConverseAPI` (if reasoning/thinking supported) +- Add model to `TestAmazonReasoningLegacyAPI` (if reasoning with Legacy API supported) + +6. **Record HTTP Interactions** +```bash +HTTPRR_RECORD=. go test -v -run TestNewModel +``` + +### Provider Implementation Checklist + +- [ ] Input struct with all parameters (Temperature, TopP, MaxTokens, etc.) +- [ ] Output struct matching API response +- [ ] Streaming struct if model supports streaming +- [ ] Error handling for provider-specific errors +- [ ] Token usage extraction +- [ ] Stop reason mapping + +## Testing Strategy + +### Why httprr? + +**Problem**: Integration tests require AWS credentials and cost money. + +**Solution**: Record HTTP interactions once, replay for fast tests. + +```bash +# Record new interactions +HTTPRR_RECORD=. go test -v -run TestName + +# Debug during recording +HTTPRR_RECORD=. HTTPRR_DEBUG=true go test -v -run TestName + +# Replay (default) +go test -v -run TestName +``` + +### Test Organization + +**Test File**: + +1. **bedrockllm_test.go**: Integration tests (requires AWS credentials) + - Model output validation (Converse and Legacy API) + - Streaming behavior (Converse and Legacy API) + - Tool calling workflows (Converse and Legacy API, with streaming variants) + - Reasoning roundtrips (Converse and Legacy API, with streaming variants) + - Caching metrics (automatic and manual caching) + - Extended thinking with tool calls + - Multi-turn caching with tools + - Client creation with different credential types (long-lived, bearer token) + +2. **bedrockllm_unit_test.go**: Unit tests (no credentials) + - Message processing logic + - Option configuration + - Cache control application + - Provider detection + +**Why separate files?** + +- Unit tests run in CI without credentials +- Integration tests record once, replay forever +- Tool tests validate complex workflows + +### Testing Non-Deterministic Tool Calls + +**Challenge**: `map[string]any` serialization order is non-deterministic. + +```go +// First run: {"a": 15, "b": 8} +// Second run: {"b": 8, "a": 15} // Different order! +``` + +**Solution**: Skip second request in replay mode (`isReplaying` check). + +```go +if isReplaying { + return nil // Don't send tool result +} +``` + +## Error Handling + +### Error Mapping Strategy + +**Why custom mapping?** + +AWS errors are provider-specific strings. Need standardized codes for client logic. + +```go +// errors.go +bedrockErrorMappings = []errorMapping{ + {patterns: []string{"throttlingexception"}, code: llms.ErrCodeRateLimit}, + {patterns: []string{"accessdenied"}, code: llms.ErrCodeAuthentication}, + // ... +} +``` + +**Usage**: +```go +if llmErr, ok := err.(*llms.Error); ok { + switch llmErr.Code { + case llms.ErrCodeRateLimit: + // Implement backoff + } +} +``` + +## Streaming Implementation + +### Event Processing Pattern + +**Both APIs use AWS SDK event streams**, but different event types: + +**Legacy API**: +```go +// Anthropic: streamingCompletionResponseChunk +types: message_start, content_block_delta, message_delta, message_stop +``` + +**Converse API**: +```go +// AWS SDK types +ConverseStreamOutputMemberContentBlockDelta +ConverseStreamOutputMemberContentBlockStart +ConverseStreamOutputMemberContentBlockStop +``` + +### Tool Call Streaming Accumulation + +**Why accumulation needed?** + +Tool arguments arrive in chunks: + +```go +// Chunk 1: {"operation" +// Chunk 2: :"multiply","a" +// Chunk 3: :15,"b":8} +``` + +**Solution**: Accumulate in `streaming.ToolCall` map, send complete call at `ContentBlockStop`. + +## Maintenance Guidelines + +### When to Use Legacy vs Converse API + +**Use Legacy API**: +- Model doesn't support Converse API +- Need Anthropic-specific cache_control format +- Debugging provider-specific issues + +**Use Converse API**: +- Default for new implementations +- Better error messages +- Unified tool calling +- Native cachePoint support + +### Adding Caching Support + +**Criteria**: +1. Model must support Anthropic prompt caching (currently only Claude 4.x) +2. Add pattern to `supportsCaching()` in `bedrockllm.go`: +```go +cachingPatterns := []string{ + "claude-opus-4", + "claude-sonnet-4", + "claude-haiku-4", + "claude-new-4", // Add new model pattern +} +``` +3. Ensure model supports minimum 1024 tokens threshold for cache activation +4. Add tests in `TestAmazonAutomaticCachingConverseAPI` and `TestAmazonAutomaticCachingLegacyAPI` + +### Common Pitfalls + +**1. Forgetting to handle nil FunctionCall** +```go +// BAD +Name: part.FunctionCall.Name // Panic if nil + +// GOOD +if part.FunctionCall == nil { + return errors.New("missing function call") +} +``` + +**2. Ignoring marshal errors** +```go +// BAD +argsJSON, _ := json.Marshal(data) + +// GOOD +argsJSON, err := json.Marshal(data) +if err != nil { + return fmt.Errorf("marshal failed: %w", err) +} +``` + +**3. Not checking tool call arguments validity** +```go +// BAD - may pass invalid JSON to tool +toolCall.FunctionCall.Arguments // No validation + +// GOOD - validate tool arguments can be parsed +var args map[string]any +if err := json.Unmarshal([]byte(toolCall.FunctionCall.Arguments), &args); err != nil { + return fmt.Errorf("invalid tool arguments: %w", err) +} +``` + +## File Organization + +``` +llms/bedrock/ +├── bedrockllm.go # Main LLM implementation, message processing, caching +├── bedrockllm_option.go # Configuration options +├── bedrockllm_test.go # Integration tests (httprr recorded) +├── bedrockllm_unit_test.go # Unit tests (no AWS required) +├── models_list.go # Model constants and documentation +├── errors.go # Error mapping +├── doc.go # Package documentation +├── tool_call_test.go # Tool call processing tests +├── llmtest_test.go # LLM interface compliance tests +└── internal/bedrockclient/ + ├── bedrockclient.go # Legacy API client + ├── bedrockclient_converse.go # Converse API client + ├── bedrockclient_util.go # Smithy validation + ├── bedrockclient_test.go # Client tests + ├── bedrockclient_integration_test.go # Client integration tests + ├── provider_anthropic.go # Anthropic-specific implementation + ├── provider_nova.go # Nova-specific implementation + ├── provider_*.go # Other providers + └── *_test.go # Provider tests +``` + +## Key Design Decisions + +### Why Separate Provider Files? + +**Problem**: Single file would be 5000+ lines with mixed concerns. + +**Solution**: Each provider in separate file with consistent interface. + +**Benefits**: +- Easy to add new providers +- Clear separation of model-specific logic +- Isolated testing + +### Why Two Cache Control Formats? + +**Legacy API**: Anthropic's `cache_control` in message content +```json +{ + "type": "text", + "text": "...", + "cache_control": {"type": "ephemeral", "ttl": "5m"} +} +``` + +**Converse API**: AWS's `cachePoint` blocks +```json +{ + "content": [ + {"text": "..."}, + {"cachePoint": {"type": "default", "ttl": "fiveMinutes"}} + ] +} +``` + +**Why support both?** +- Legacy API: Anthropic `cache_control` format required (embedded in content blocks) +- Converse API: AWS `cachePoint` format required (separate content block type) +- Automatic caching abstracts the difference by using appropriate format based on API + +### Message Processing: Content Parts to Messages + +**Key Insight**: `llms.MessageContent` supports multiple content parts (text, images, tool calls), but provider APIs may require them as separate messages or flattened arrays. + +**Processing Flow**: +```go +// Input: Single MessageContent with multiple parts +llms.MessageContent{ + Role: llms.ChatMessageTypeHuman, + Parts: [TextPart("Describe"), BinaryPart(imageData)] } -resp, err := llm.GenerateContent(ctx, messages, - llms.WithStreamingFunc(streamingFunc), -) +// Output: Flat message array for provider API +[ + Message{Type: "text", Content: "Describe"}, + Message{Type: "image", Content: base64Data, MimeType: "image/jpeg"} +] ``` -## Tool Calling +**Why flatten?** +- Anthropic Legacy API: Requires flat content array per message +- Nova/other providers: Each content type is separate array element +- Simplifies provider-specific serialization logic -```go -tools := []llms.Tool{{ - Type: "function", - Function: &llms.FunctionDefinition{ - Name: "calculator", - Description: "Perform arithmetic operations", - Parameters: map[string]any{ - "type": "object", - "properties": map[string]any{ - "operation": map[string]any{ - "type": "string", - "enum": []string{"add", "subtract", "multiply", "divide"}, - }, - "a": map[string]any{"type": "number"}, - "b": map[string]any{"type": "number"}, - }, - "required": []string{"operation", "a", "b"}, - }, - }, -}} +## Debugging Guide -resp, err := llm.GenerateContent(ctx, messages, - llms.WithTools(tools), -) -``` - -## Configuration Options - -```go -// Custom AWS client -client := bedrockruntime.NewFromConfig(cfg) -llm, err := bedrock.New(bedrock.WithClient(client)) - -// Model selection -llm, err := bedrock.New(bedrock.WithModel(bedrock.ModelAmazonNovaProV1)) - -// Enable Converse API (recommended for new applications) -llm, err := bedrock.New(bedrock.WithConverseAPI()) - -// Callback handler -llm, err := bedrock.New(bedrock.WithCallback(handler)) -``` - -## Key Differences - -### Converse API vs Legacy API -- **Converse API**: Unified interface, better tool calling, reasoning support -- **Legacy API**: Direct model-specific implementations, broader model compatibility - -### Model Capabilities -- **Tool Calling**: Nova, Anthropic Claude 4/3.7/3.5, Cohere Command-R+ -- **Reasoning**: Anthropic Claude 4/3.7, Amazon Nova models -- **Streaming**: Most models (except AI21 Jamba series) -- **Multimodal**: Nova Pro/Lite, Claude models - -## Environment Setup +### Enable HTTP Logging ```bash -export AWS_ACCESS_KEY_ID=your_access_key -export AWS_SECRET_ACCESS_KEY=your_secret_key -export AWS_REGION=us-east-1 +HTTPRR_DEBUG=true go test -v -run TestName ``` -## Testing +### Check Cache Metrics -```bash -# Basic functionality -go test -v -run TestAmazonOutput - -# Streaming support -go test -v -run TestAmazonStreamingOutput - -# Tool calling -go test -v -run TestAmazonToolCalling +```go +resp.Choices[0].GenerationInfo["CacheReadInputTokens"] // Tokens read from cache +resp.Choices[0].GenerationInfo["CacheCreationInputTokens"] // Tokens written to cache ``` -For comprehensive examples, see the [examples directory](../../examples/) in the langchaingo repository. +### Validate Tool Call Arguments + +Look for empty `Arguments` in logs - indicates parsing issue: +```go +if len(arguments) == 0 { + // Check FunctionCall.Arguments JSON validity +} +``` + +### Common Errors + +**"unsupported message type"** +- Added new ContentPart type without handling in processMessages() + +**"role not supported"** +- Provider doesn't support message role (e.g., Function role) + +**"completed due to max_tokens"** +- Increase MaxTokens in request + +**"cached HTTP response not found"** +- httprr recording changed, re-record with `HTTPRR_RECORD=.` + +## Performance Considerations + +### Automatic Caching Impact + +**First request**: Cache creation overhead (~50ms) +**Subsequent requests**: 90% token cost reduction, ~20% latency reduction + +**Best for**: +- Long conversations (3+ turns) +- Large system prompts (>1024 tokens) +- Repeated context (tools, RAG documents) + +### Streaming Latency + +**Time to first token**: 200-500ms (depending on model) +**Chunk frequency**: Every 20-50ms + +**Use streaming when**: +- User-facing chat interfaces +- Long responses (>500 tokens) +- Real-time feedback needed + +## Future Enhancements + +### Potential Improvements + +1. **Converse API Migration** + - Move all models to Converse API + - Deprecate Legacy API providers + - Why: Simpler maintenance, better consistency + +2. **Smart Cache TTL Selection** + - 5m for short conversations + - 1h for long sessions + - Why: Optimize cost vs cache hit rate + +3. **Parallel Tool Calls** + - Support multiple simultaneous tools + - Why: Some models return parallel tool calls + +4. **Structured Output** + - JSON schema validation + - Why: Type-safe responses + +## Contributing + +### Before Adding Features + +1. Check if Converse API supports it natively +2. Consider impact on both API paths +3. Add tests for both streaming and non-streaming +4. Update httprr recordings + +### Code Review Checklist + +- [ ] Error handling for all AWS SDK calls +- [ ] Nil checks for optional fields +- [ ] Cache control doesn't break non-caching models +- [ ] Tool calling tested with real model +- [ ] httprr recordings committed +- [ ] Documentation updated + +## Supported Model Matrix + +| Provider | Tool Calling | Reasoning | Streaming | Multimodal | Caching | +|----------|-------------|-----------|-----------|------------|---------| +| Claude 4.6 | ✅ | ✅ | ✅ | ✅ | ✅ | +| Claude 4.5 | ✅ | ✅ | ✅ | ✅ | ✅ | +| Claude 4.1 | ✅ | ✅ | ✅ | ✅ | ✅ | +| Claude 4.0 | ✅ | ✅ | ✅ | ✅ | ✅ | +| Claude 3.7 | ✅ | ✅ | ✅ | ❌ | ❌ | +| Claude 3.5 | ✅ | ❌ | ✅ | ❌ | ❌ | +| Nova 2/Pro/Lite | ✅ | ❌ | ✅ | ✅ | ❌ | +| Llama 4 | Limited | ❌ | ✅ | ✅ | ❌ | +| Cohere R+ | ✅ | ❌ | ✅ | ❌ | ❌ | +| DeepSeek V3.2 | ✅ | ❌ | ✅ | ❌ | ❌ | +| DeepSeek R1 | ❌ | ✅ | ✅ | ❌ | ❌ | +| AI21 Jamba | Limited* | ❌ | ✅** | ❌ | ❌ | +| OpenAI GPT (OSS) | ✅ | ✅ | ✅ | ❌ | ❌ | +| Qwen3 | Varies*** | ❌ | ✅ | Some | ❌ | +| Mistral | ✅**** | ❌ | ✅ | ❌ | ❌ | +| Moonshot Kimi | ✅***** | ✅ | ✅ | ❌ | ❌ | +| GLM-4.7 | ❌****** | ❌ | ✅ | ❌ | ❌ | + +*AI21 Jamba: Rate limits prevent extensive tool calling testing +**AI21 Jamba: Streaming supported only with Converse API +***Qwen3: Most models support tools, except Qwen3-VL (unstable in streaming) +****Mistral: Large3 and Large2402 support tools, MagistralSmall2509 does not +*****Moonshot: K2.5 supports tools, K2-Thinking is unstable +******GLM models: Backend incompatibility with Converse API tool format (requires string instead of JSON) + +See `models_list.go` for complete model list and detailed capabilities. diff --git a/llms/bedrock/bedrock_tool_integration_test.go b/llms/bedrock/bedrock_tool_integration_test.go deleted file mode 100644 index 438a6190..00000000 --- a/llms/bedrock/bedrock_tool_integration_test.go +++ /dev/null @@ -1,200 +0,0 @@ -package bedrock_test - -import ( - "context" - "encoding/json" - "net/http" - "os" - "testing" - - "github.com/stretchr/testify/require" - "github.com/vxcontrol/langchaingo/internal/httprr" - "github.com/vxcontrol/langchaingo/llms" - "github.com/vxcontrol/langchaingo/llms/bedrock" -) - -func TestBedrockAnthropicToolCalling(t *testing.T) { //nolint:funlen - ctx := context.Background() - - httprr.SkipIfNoCredentialsAndRecordingMissing(t, "AWS_ACCESS_KEY_ID") - - rr := httprr.OpenForTest(t, http.DefaultTransport) - defer rr.Close() - - // Only run tests in parallel when not recording (to avoid rate limits) - if !rr.Recording() { - t.Parallel() - } - - // Configure AWS client to use httprr transport - client, err := setUpTestWithTransport(rr) - if err != nil { - t.Fatal(err) - } - - llm, err := bedrock.New(bedrock.WithClient(client)) - if err != nil { - t.Fatal(err) - } - - // Define a weather tool - weatherTool := llms.Tool{ - Type: "function", - Function: &llms.FunctionDefinition{ - Name: "get_weather", - Description: "Get the current weather for a location", - Parameters: map[string]any{ - "type": "object", - "properties": map[string]any{ - "location": map[string]any{ - "type": "string", - "description": "The city and state, e.g. San Francisco, CA", - }, - "unit": map[string]any{ - "type": "string", - "enum": []string{"celsius", "fahrenheit"}, - "description": "The unit of temperature", - }, - }, - "required": []string{"location"}, - }, - }, - } - - t.Run("Anthropic Claude 3 with tool calling", func(t *testing.T) { - // Skip if not recording and no credentials - if !rr.Recording() && !hasAWSCredentials() { - t.Skip("Skipping test: no AWS credentials and not recording") - } - - msgs := []llms.MessageContent{ - llms.TextParts(llms.ChatMessageTypeHuman, "What's the weather like in New York?"), - } - - resp, err := llm.GenerateContent(ctx, msgs, - llms.WithModel(bedrock.ModelAnthropicClaudeHaiku45), - llms.WithTools([]llms.Tool{weatherTool}), - llms.WithMaxTokens(512), - ) - if err != nil { - t.Fatal(err) - } - - require.NotNil(t, resp) - require.NotEmpty(t, resp.Choices) - - // Check if the model wants to use the tool - choice := resp.Choices[0] - if len(choice.ToolCalls) > 0 { - t.Logf("Model requested tool call: %+v", choice.ToolCalls[0]) - - // Verify tool call structure - toolCall := choice.ToolCalls[0] - require.Equal(t, "function", toolCall.Type) - require.NotNil(t, toolCall.FunctionCall) - require.Equal(t, "get_weather", toolCall.FunctionCall.Name) - - // Parse arguments - var args map[string]any - err := json.Unmarshal([]byte(toolCall.FunctionCall.Arguments), &args) - require.NoError(t, err) - require.Contains(t, args, "location") - - // Add assistant response with tool call - assistantResponse := llms.MessageContent{ - Role: llms.ChatMessageTypeAI, - Parts: []llms.ContentPart{ - llms.ToolCall{ - ID: toolCall.ID, - Type: toolCall.Type, - FunctionCall: &llms.FunctionCall{ - Name: toolCall.FunctionCall.Name, - Arguments: toolCall.FunctionCall.Arguments, - }, - }, - }, - } - msgs = append(msgs, assistantResponse) - - // Add tool response - toolResponse := llms.MessageContent{ - Role: llms.ChatMessageTypeTool, - Parts: []llms.ContentPart{ - llms.ToolCallResponse{ - ToolCallID: toolCall.ID, - Name: "get_weather", - Content: "It's currently 72°F and sunny in New York", - }, - }, - } - msgs = append(msgs, toolResponse) - - resp2, err := llm.GenerateContent(ctx, msgs, - llms.WithModel(bedrock.ModelAnthropicClaudeHaiku45), - llms.WithMaxTokens(512), - ) - require.NoError(t, err) - require.NotNil(t, resp2) - require.NotEmpty(t, resp2.Choices) - - t.Logf("Final response: %s", resp2.Choices[0].Content) - } else { - t.Logf("Model response without tool call: %s", choice.Content) - } - }) - - t.Run("Multiple tools", func(t *testing.T) { - // Skip if not recording and no credentials - if !rr.Recording() && !hasAWSCredentials() { - t.Skip("Skipping test: no AWS credentials and not recording") - } - - calculatorTool := llms.Tool{ - Type: "function", - Function: &llms.FunctionDefinition{ - Name: "calculate", - Description: "Perform mathematical calculations", - Parameters: map[string]any{ - "type": "object", - "properties": map[string]any{ - "expression": map[string]any{ - "type": "string", - "description": "The mathematical expression to evaluate", - }, - }, - "required": []string{"expression"}, - }, - }, - } - - msgs := []llms.MessageContent{ - llms.TextParts(llms.ChatMessageTypeHuman, "What's 123 * 456 and what's the weather in Paris?"), - } - - resp, err := llm.GenerateContent(ctx, msgs, - llms.WithModel(bedrock.ModelAnthropicClaudeHaiku45), - llms.WithTools([]llms.Tool{weatherTool, calculatorTool}), - llms.WithMaxTokens(512), - ) - if err != nil { - t.Fatal(err) - } - - require.NotNil(t, resp) - require.NotEmpty(t, resp.Choices) - - // Check for multiple tool calls - choice := resp.Choices[0] - t.Logf("Number of tool calls: %d", len(choice.ToolCalls)) - for i, tc := range choice.ToolCalls { - t.Logf("Tool call %d: %s(%s)", i, tc.FunctionCall.Name, tc.FunctionCall.Arguments) - } - }) -} - -func hasAWSCredentials() bool { - // Check if AWS credentials are available - _, hasKey := os.LookupEnv("AWS_ACCESS_KEY_ID") - _, hasProfile := os.LookupEnv("AWS_PROFILE") - return hasKey || hasProfile -} diff --git a/llms/bedrock/bedrockllm.go b/llms/bedrock/bedrockllm.go index fc3395ff..156f01a2 100644 --- a/llms/bedrock/bedrockllm.go +++ b/llms/bedrock/bedrockllm.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "errors" + "fmt" + "strings" + "time" "github.com/vxcontrol/langchaingo/callbacks" "github.com/vxcontrol/langchaingo/llms" @@ -17,11 +20,12 @@ const defaultModel = ModelAnthropicClaudeHaiku45 // LLM is a Bedrock LLM implementation. type LLM struct { - modelID string - client *bedrockclient.Client - converseClient *bedrockclient.ConverseClient - useConverseAPI bool - CallbacksHandler callbacks.Handler + modelID string + client *bedrockclient.Client + converseClient *bedrockclient.ConverseClient + useConverseAPI bool + enableAutoCaching bool + CallbacksHandler callbacks.Handler } // New creates a new Bedrock LLM implementation. @@ -36,11 +40,12 @@ func NewWithContext(ctx context.Context, opts ...Option) (*LLM, error) { return nil, err } return &LLM{ - client: c, - converseClient: converseC, - useConverseAPI: o.useConverseAPI, - modelID: o.modelID, - CallbacksHandler: o.callbackHandler, + client: c, + converseClient: converseC, + useConverseAPI: o.useConverseAPI, + enableAutoCaching: o.enableAutoCaching, + modelID: o.modelID, + CallbacksHandler: o.callbackHandler, }, nil } @@ -97,11 +102,19 @@ func (l *LLM) GenerateContent(ctx context.Context, messages []llms.MessageConten // generateContentWithConverseAPI uses the unified Converse API func (l *LLM) generateContentWithConverseAPI(ctx context.Context, messages []llms.MessageContent, opts llms.CallOptions) (*llms.ContentResponse, error) { - m, err := processMessages(messages) + // Apply automatic caching to bedrock messages if enabled + shouldAutoCache := l.enableAutoCaching && l.supportsCaching(opts.Model) + m, err := processMessagesWithCaching(messages, shouldAutoCache) if err != nil { return nil, err } + // Check if caching should be enabled + // Caching is enabled if either: + // 1. Automatic caching is enabled and model supports it + // 2. Manual cache control is present in messages + enableCaching := shouldAutoCache || checkIfCachingRequested(messages) + // Build Converse input input := &bedrockclient.ConverseInput{ ModelID: opts.Model, @@ -109,6 +122,7 @@ func (l *LLM) generateContentWithConverseAPI(ctx context.Context, messages []llm Tools: opts.Tools, StreamingFunc: opts.StreamingFunc, ReasoningConfig: opts.Reasoning, + EnableCaching: enableCaching, } // Set inference parameters @@ -142,7 +156,9 @@ func (l *LLM) generateContentWithConverseAPI(ctx context.Context, messages []llm // generateContentWithLegacyAPI uses the original model-specific implementations func (l *LLM) generateContentWithLegacyAPI(ctx context.Context, messages []llms.MessageContent, opts llms.CallOptions) (*llms.ContentResponse, error) { - m, err := processMessages(messages) + // Apply automatic caching to bedrock messages if enabled + shouldAutoCache := l.enableAutoCaching && l.supportsCaching(opts.Model) + m, err := processMessagesWithCaching(messages, shouldAutoCache) if err != nil { return nil, err } @@ -163,16 +179,45 @@ func (l *LLM) generateContentWithLegacyAPI(ctx context.Context, messages []llms. } func processMessages(messages []llms.MessageContent) ([]bedrockclient.Message, error) { + return processMessagesWithCaching(messages, false) +} + +func processMessagesWithCaching(messages []llms.MessageContent, autoCaching bool) ([]bedrockclient.Message, error) { bedrockMsgs := make([]bedrockclient.Message, 0, len(messages)) for _, m := range messages { for _, part := range m.Parts { switch part := part.(type) { + case CachedContent: + // Handle cached content with cache control + cacheControl := convertCacheControl(part.CacheControl) + // Process the wrapped content + switch wrapped := part.ContentPart.(type) { + case llms.TextContent: + bedrockMsgs = append(bedrockMsgs, bedrockclient.Message{ + Role: m.Role, + Content: wrapped.Text, + Type: "text", + Reasoning: wrapped.Reasoning, + CacheControl: cacheControl, + }) + case llms.BinaryContent: + bedrockMsgs = append(bedrockMsgs, bedrockclient.Message{ + Role: m.Role, + Content: string(wrapped.Data), + MimeType: wrapped.MIMEType, + Type: "image", + CacheControl: cacheControl, + }) + default: + return nil, errors.New("unsupported cached content type") + } case llms.TextContent: bedrockMsgs = append(bedrockMsgs, bedrockclient.Message{ - Role: m.Role, - Content: part.Text, - Type: "text", + Role: m.Role, + Content: part.Text, + Type: "text", + Reasoning: part.Reasoning, }) case llms.BinaryContent: bedrockMsgs = append(bedrockMsgs, bedrockclient.Message{ @@ -182,10 +227,13 @@ func processMessages(messages []llms.MessageContent) ([]bedrockclient.Message, e Type: "image", }) case llms.ToolCall: + if part.FunctionCall == nil { + return nil, errors.New("tool call missing function call data") + } var arguments map[string]any - if part.FunctionCall != nil { + if part.FunctionCall.Arguments != "" { if err := json.Unmarshal([]byte(part.FunctionCall.Arguments), &arguments); err != nil { - return nil, err + return nil, fmt.Errorf("failed to unmarshal tool call arguments: %w", err) } } bedrockMsgs = append(bedrockMsgs, bedrockclient.Message{ @@ -208,11 +256,103 @@ func processMessages(messages []llms.MessageContent) ([]bedrockclient.Message, e }, }) default: + // Check if it's unknown type - might be a specific provider type return nil, errors.New("unsupported message type") } } } + + // Apply automatic caching if requested + if autoCaching { + applyAutomaticCaching(bedrockMsgs) + } + return bedrockMsgs, nil } +// applyAutomaticCaching adds cache control to the last assistant or tool message +// to enable conversation history caching without manual intervention. +func applyAutomaticCaching(messages []bedrockclient.Message) { + if len(messages) == 0 { + return + } + + // Find the last assistant or tool message before the current user turn + lastCacheableIdx := -1 + for i := len(messages) - 1; i >= 0; i-- { + // Skip the last message if it's from human (current turn) + if i == len(messages)-1 && messages[i].Role == llms.ChatMessageTypeHuman { + continue + } + // Find last assistant or tool message + if messages[i].Role == llms.ChatMessageTypeAI || messages[i].Role == llms.ChatMessageTypeTool { + lastCacheableIdx = i + break + } + } + + if lastCacheableIdx == -1 { + return + } + + // Add cache control to the selected message + if messages[lastCacheableIdx].CacheControl == nil { + messages[lastCacheableIdx].CacheControl = &bedrockclient.CacheControl{ + Type: "ephemeral", + TTL: "5m", + } + } +} + +// convertCacheControl converts shared llms.CacheControl to Bedrock-specific format +func convertCacheControl(llmCache *llms.CacheControl) *bedrockclient.CacheControl { + if llmCache == nil { + return nil + } + + bedrockCache := &bedrockclient.CacheControl{ + Type: llmCache.Type, + } + + // Convert duration to TTL string + if llmCache.Duration > 0 { + if llmCache.Duration >= time.Hour { + bedrockCache.TTL = "1h" + } else { + bedrockCache.TTL = "5m" + } + } + + return bedrockCache +} + +// checkIfCachingRequested checks if any messages contain CachedContent +func checkIfCachingRequested(messages []llms.MessageContent) bool { + for _, msg := range messages { + for _, part := range msg.Parts { + if _, ok := part.(CachedContent); ok { + return true + } + } + } + return false +} + +// supportsCaching checks if the model supports prompt caching +func (l *LLM) supportsCaching(modelID string) bool { + // All Claude 4.x models support prompt caching (Opus, Sonnet, Haiku) + cachingPatterns := []string{ + "claude-opus-4", + "claude-sonnet-4", + "claude-haiku-4", + } + + for _, pattern := range cachingPatterns { + if strings.Contains(modelID, pattern) { + return true + } + } + return false +} + var _ llms.Model = (*LLM)(nil) diff --git a/llms/bedrock/bedrockllm_option.go b/llms/bedrock/bedrockllm_option.go index 22f22e8c..26546222 100644 --- a/llms/bedrock/bedrockllm_option.go +++ b/llms/bedrock/bedrockllm_option.go @@ -1,7 +1,10 @@ package bedrock import ( + "time" + "github.com/vxcontrol/langchaingo/callbacks" + "github.com/vxcontrol/langchaingo/llms" "github.com/aws/aws-sdk-go-v2/service/bedrockruntime" ) @@ -10,11 +13,12 @@ import ( type Option func(*options) type options struct { - modelProvider string - modelID string - client *bedrockruntime.Client - callbackHandler callbacks.Handler - useConverseAPI bool + modelProvider string + modelID string + client *bedrockruntime.Client + callbackHandler callbacks.Handler + useConverseAPI bool + enableAutoCaching bool } // WithModel allows setting a custom modelId. @@ -67,13 +71,95 @@ func WithCallback(callbackHandler callbacks.Handler) Option { // - Reasoning content support for Claude 3.7+ and Nova models // - Multimodal input support (text, images, documents) // - Better error handling and response consistency +// - Prompt caching support via cachePoint (requires AWS SDK types) // // Supported models: All Anthropic Claude, Amazon Nova, Meta Llama, // Cohere Command, and AI21 Jamba models available through Bedrock. // // Note: This is the recommended approach for new applications. +// +// Prompt Caching: +// - Legacy API (InvokeModel) supports Anthropic's cache_control format +// - Converse API supports cachePoint via SystemContentBlockMemberCachePoint +// - Cache metrics are returned in response.Usage (CacheReadInputTokens, CacheWriteInputTokens) +// - Requires minimum tokens per checkpoint (1024 for Sonnet 4.5, 4096 for Haiku 4.5) +// - Supports 5m and 1h TTL for Claude 4.x models func WithConverseAPI() Option { return func(o *options) { o.useConverseAPI = true } } + +// WithAutomaticCaching enables automatic prompt caching for supported Anthropic models. +// +// When enabled, caching is automatically applied for models matching these patterns: +// - claude-opus-4 (includes 4.6, 4.5, 4.1, 4.0) +// - claude-sonnet-4 (includes 4.6, 4.5, 4.0) +// - claude-haiku-4 (includes 4.5) +// +// The caching strategy automatically: +// - Adds cache points to system prompts +// - Adds cache points to conversation history (last message before new user input) +// - Uses ephemeral 5-minute TTL by default +// +// Benefits: +// - 90% cost reduction on cached input tokens +// - No manual cache control wrapper needed on client side +// - Transparent caching without modifying message chains +// +// Note: Automatic caching works with both Legacy and Converse APIs. +func WithAutomaticCaching() Option { + return func(o *options) { + o.enableAutoCaching = true + } +} + +// EphemeralCache creates a standard ephemeral cache control for Bedrock with 5-minute duration. +func EphemeralCache() *llms.CacheControl { + return &llms.CacheControl{ + Type: "ephemeral", + Duration: 5 * time.Minute, + } +} + +// EphemeralCacheOneHour creates a 1-hour ephemeral cache control for Bedrock. +// Supported by Claude Opus 4.5, Haiku 4.5, and Sonnet 4.5. +func EphemeralCacheOneHour() *llms.CacheControl { + return &llms.CacheControl{ + Type: "ephemeral", + Duration: time.Hour, + } +} + +// CachedContent represents content with caching instructions for Bedrock. +// This wraps any ContentPart and adds cache control metadata. +// +// Note: For most use cases, prefer using bedrock.WithAutomaticCaching() option +// which automatically applies caching to supported Anthropic models (Claude 4.x). +// This manual wrapper is only needed for fine-grained cache control. +// +// Automatic caching is supported in both Legacy and Converse APIs. +type CachedContent struct { + llms.ContentPart + CacheControl *llms.CacheControl `json:"cache_control,omitempty"` +} + +// WithCacheControl wraps content with cache control instructions for Bedrock. +// This allows explicit control over what content should be cached. +// +// Recommended: Use bedrock.WithAutomaticCaching() option instead for transparent caching. +// +// Manual usage (when fine-grained control is needed): +// +// bedrock.WithCacheControl( +// llms.TextPart("long context..."), +// bedrock.EphemeralCache(), +// ) +// +// Supported models: Claude Opus 4, Sonnet 4, Haiku 4 and their variants. +func WithCacheControl(content llms.ContentPart, control *llms.CacheControl) CachedContent { + return CachedContent{ + ContentPart: content, + CacheControl: control, + } +} diff --git a/llms/bedrock/bedrockllm_test.go b/llms/bedrock/bedrockllm_test.go index 05f5d6b4..285e3c88 100644 --- a/llms/bedrock/bedrockllm_test.go +++ b/llms/bedrock/bedrockllm_test.go @@ -15,7 +15,9 @@ import ( "github.com/vxcontrol/langchaingo/llms/streaming" "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/bedrockruntime" + "github.com/aws/smithy-go/auth/bearer" ) func setUpTestWithTransport(rr *httprr.RecordReplay) (*bedrockruntime.Client, error) { @@ -93,13 +95,15 @@ func TestAmazonOutputConverseAPI(t *testing.T) { bedrock.ModelAmazonNovaMicroV1, // Anthropic models + bedrock.ModelAnthropicClaudeOpus46, + bedrock.ModelAnthropicClaudeSonnet46, bedrock.ModelAnthropicClaudeOpus45, bedrock.ModelAnthropicClaudeHaiku45, bedrock.ModelAnthropicClaudeSonnet45, bedrock.ModelAnthropicClaudeOpus41, - bedrock.ModelAnthropicClaudeOpus4, + // bedrock.ModelAnthropicClaudeOpus4, // Model is deprecated bedrock.ModelAnthropicClaudeSonnet4, - bedrock.ModelAnthropicClaude37Sonnet, + // bedrock.ModelAnthropicClaude37Sonnet, // Model is deprecated bedrock.ModelAnthropicClaude35Haiku, // Cohere models @@ -108,18 +112,43 @@ func TestAmazonOutputConverseAPI(t *testing.T) { // Meta models // bedrock.ModelMetaLlama4MaverickInstructV1, // Unavailable for MENA users - // bedrock.ModelMetaLlama4ScoutInstructV1, // Unavailable for MENA users + // bedrock.ModelMetaLlama4ScoutInstructV1, // Unavailable for MENA users bedrock.ModelMetaLlama3370bInstructV1, - // bedrock.ModelMetaLlama3211bInstructV1, // Unavailable for MENA users - // bedrock.ModelMetaLlama3211bInstructV1, // Unavailable for MENA users - // bedrock.ModelMetaLlama3290bInstructV1, // Unavailable for MENA users + // bedrock.ModelMetaLlama3211bInstructV1, // Unavailable for MENA users + // bedrock.ModelMetaLlama3211bInstructV1, // Unavailable for MENA users + // bedrock.ModelMetaLlama3290bInstructV1, // Unavailable for MENA users bedrock.ModelMetaLlama3170bInstructV1, - // bedrock.ModelMetaLlama318bInstructV1, // Unavailable for MENA users + // bedrock.ModelMetaLlama318bInstructV1, // Unavailable for MENA users bedrock.ModelMetaLlama370bInstructV1, bedrock.ModelMetaLlama38bInstructV1, // DeepSeek models bedrock.ModelDeepSeekR1V1, + bedrock.ModelDeepSeekV32, + + // OpenAI models + bedrock.ModelOpenAIGptOss120BV1, + bedrock.ModelOpenAIGptOss20BV1, + + // Qwen models + bedrock.ModelQwen3Next80BA3B, + bedrock.ModelQwen3VL235BA22B, + bedrock.ModelQwen332BV1, + bedrock.ModelQwen3Coder30BA3BV1, + bedrock.ModelQwen3CoderNext, + + // Mistral models + bedrock.ModelMistralLarge3, + bedrock.ModelMistralMagistralSmall2509, + bedrock.ModelMistralLarge2402V1, + + // Moonshot models + bedrock.ModelMoonshotKimiK25, + bedrock.ModelMoonshotKimiK2Thinking, + + // Z.AI models + bedrock.ModelGLM47, + bedrock.ModelGLM47Flash, } for _, model := range models { @@ -283,13 +312,15 @@ func TestAmazonStreamingOutputConverseAPI(t *testing.T) { //nolint:funlen bedrock.ModelAmazonNovaMicroV1, // Anthropic models + bedrock.ModelAnthropicClaudeOpus46, + bedrock.ModelAnthropicClaudeSonnet46, bedrock.ModelAnthropicClaudeOpus45, bedrock.ModelAnthropicClaudeHaiku45, bedrock.ModelAnthropicClaudeSonnet45, bedrock.ModelAnthropicClaudeOpus41, - bedrock.ModelAnthropicClaudeOpus4, + // bedrock.ModelAnthropicClaudeOpus4, // Model is deprecated bedrock.ModelAnthropicClaudeSonnet4, - bedrock.ModelAnthropicClaude37Sonnet, + // bedrock.ModelAnthropicClaude37Sonnet, // Model is deprecated bedrock.ModelAnthropicClaude35Haiku, // Cohere models (only Command-R supports streaming and Converse API) @@ -298,18 +329,43 @@ func TestAmazonStreamingOutputConverseAPI(t *testing.T) { //nolint:funlen // Meta models // bedrock.ModelMetaLlama4MaverickInstructV1, // Unavailable for MENA users - // bedrock.ModelMetaLlama4ScoutInstructV1, // Unavailable for MENA users + // bedrock.ModelMetaLlama4ScoutInstructV1, // Unavailable for MENA users bedrock.ModelMetaLlama3370bInstructV1, - // bedrock.ModelMetaLlama3211bInstructV1, // Unavailable for MENA users - // bedrock.ModelMetaLlama3211bInstructV1, // Unavailable for MENA users - // bedrock.ModelMetaLlama3290bInstructV1, // Unavailable for MENA users + // bedrock.ModelMetaLlama3211bInstructV1, // Unavailable for MENA users + // bedrock.ModelMetaLlama3211bInstructV1, // Unavailable for MENA users + // bedrock.ModelMetaLlama3290bInstructV1, // Unavailable for MENA users bedrock.ModelMetaLlama3170bInstructV1, - // bedrock.ModelMetaLlama318bInstructV1, // Unavailable for MENA users + // bedrock.ModelMetaLlama318bInstructV1, // Unavailable for MENA users bedrock.ModelMetaLlama370bInstructV1, bedrock.ModelMetaLlama38bInstructV1, // DeepSeek models bedrock.ModelDeepSeekR1V1, + bedrock.ModelDeepSeekV32, + + // OpenAI models + bedrock.ModelOpenAIGptOss120BV1, + bedrock.ModelOpenAIGptOss20BV1, + + // Qwen models + bedrock.ModelQwen3Next80BA3B, + bedrock.ModelQwen3VL235BA22B, + bedrock.ModelQwen332BV1, + bedrock.ModelQwen3Coder30BA3BV1, + bedrock.ModelQwen3CoderNext, + + // Mistral models + bedrock.ModelMistralLarge3, + bedrock.ModelMistralMagistralSmall2509, + bedrock.ModelMistralLarge2402V1, + + // Moonshot models + bedrock.ModelMoonshotKimiK25, + bedrock.ModelMoonshotKimiK2Thinking, + + // Z.AI models + bedrock.ModelGLM47, + bedrock.ModelGLM47Flash, } for _, model := range models { @@ -569,7 +625,7 @@ func TestAmazonNova(t *testing.T) { } } -func TestAnthropicNovaImage(t *testing.T) { +func TestAmazonNovaImage(t *testing.T) { httprr.SkipIfNoCredentialsAndRecordingMissing(t, "AWS_ACCESS_KEY_ID") rr := httprr.OpenForTest(t, http.DefaultTransport) @@ -672,13 +728,15 @@ func TestAmazonToolCallingConverseAPI(t *testing.T) { bedrock.ModelAmazonNovaMicroV1, // Anthropic models + bedrock.ModelAnthropicClaudeOpus46, + bedrock.ModelAnthropicClaudeSonnet46, bedrock.ModelAnthropicClaudeOpus45, bedrock.ModelAnthropicClaudeHaiku45, bedrock.ModelAnthropicClaudeSonnet45, // bedrock.ModelAnthropicClaudeOpus41, // Has very hard rate limits - bedrock.ModelAnthropicClaudeOpus4, + // bedrock.ModelAnthropicClaudeOpus4, // Model is deprecated bedrock.ModelAnthropicClaudeSonnet4, - bedrock.ModelAnthropicClaude37Sonnet, + // bedrock.ModelAnthropicClaude37Sonnet, // Model is deprecated bedrock.ModelAnthropicClaude35Haiku, // Cohere models (only Command-R supports streaming and Converse API) @@ -699,6 +757,31 @@ func TestAmazonToolCallingConverseAPI(t *testing.T) { // DeepSeek models // bedrock.ModelDeepSeekR1V1, // Not supported for tool calling + bedrock.ModelDeepSeekV32, + + // OpenAI models + bedrock.ModelOpenAIGptOss120BV1, + bedrock.ModelOpenAIGptOss20BV1, + + // Qwen models + bedrock.ModelQwen3Next80BA3B, + bedrock.ModelQwen3VL235BA22B, + bedrock.ModelQwen332BV1, + bedrock.ModelQwen3Coder30BA3BV1, + bedrock.ModelQwen3CoderNext, + + // Mistral models + bedrock.ModelMistralLarge3, + // bedrock.ModelMistralMagistralSmall2509, // Not supported for tool calling + bedrock.ModelMistralLarge2402V1, + + // Moonshot models + bedrock.ModelMoonshotKimiK25, + // bedrock.ModelMoonshotKimiK2Thinking, // Not stable for tool calling + + // Z.AI models + // bedrock.ModelGLM47, // Tool calling not supported (backend requires string input instead of JSON) + // bedrock.ModelGLM47Flash, // Tool calling not supported (backend requires string input instead of JSON) } for _, model := range toolCallModels { @@ -790,13 +873,15 @@ func TestAmazonToolCallingStreamingConverseAPI(t *testing.T) { bedrock.ModelAmazonNovaMicroV1, // Anthropic models + bedrock.ModelAnthropicClaudeOpus46, + bedrock.ModelAnthropicClaudeSonnet46, bedrock.ModelAnthropicClaudeOpus45, bedrock.ModelAnthropicClaudeHaiku45, bedrock.ModelAnthropicClaudeSonnet45, // bedrock.ModelAnthropicClaudeOpus41, // Has very hard rate limits - bedrock.ModelAnthropicClaudeOpus4, + // bedrock.ModelAnthropicClaudeOpus4, // Model is deprecated bedrock.ModelAnthropicClaudeSonnet4, - bedrock.ModelAnthropicClaude37Sonnet, + // bedrock.ModelAnthropicClaude37Sonnet, // Model is deprecated bedrock.ModelAnthropicClaude35Haiku, // Cohere models (only Command-R supports streaming and Converse API) @@ -817,6 +902,31 @@ func TestAmazonToolCallingStreamingConverseAPI(t *testing.T) { // DeepSeek models // bedrock.ModelDeepSeekR1V1, // Not supported for tool calling + bedrock.ModelDeepSeekV32, + + // OpenAI models + bedrock.ModelOpenAIGptOss120BV1, + bedrock.ModelOpenAIGptOss20BV1, + + // Qwen models + bedrock.ModelQwen3Next80BA3B, + // bedrock.ModelQwen3VL235BA22B, // Not stable for tool calling + bedrock.ModelQwen332BV1, + bedrock.ModelQwen3Coder30BA3BV1, + bedrock.ModelQwen3CoderNext, + + // Mistral models + bedrock.ModelMistralLarge3, + // bedrock.ModelMistralMagistralSmall2509, // Not supported for tool calling + // bedrock.ModelMistralLarge2402V1, // Not supported for tool calling in streaming + + // Moonshot models + bedrock.ModelMoonshotKimiK25, + // bedrock.ModelMoonshotKimiK2Thinking, // Not stable for tool calling + + // Z.AI models + // bedrock.ModelGLM47, // Tool calling not supported (backend requires string input instead of JSON) + // bedrock.ModelGLM47Flash, // Tool calling not supported (backend requires string input instead of JSON) } for _, model := range streamingToolCallModels { @@ -943,12 +1053,18 @@ func TestAmazonReasoningConverseAPI(t *testing.T) { } reasoningModels := []string{ + bedrock.ModelAnthropicClaudeOpus46, + bedrock.ModelAnthropicClaudeSonnet46, bedrock.ModelAnthropicClaudeOpus45, + bedrock.ModelAnthropicClaudeHaiku45, bedrock.ModelAnthropicClaudeSonnet45, - bedrock.ModelAnthropicClaudeOpus41, - bedrock.ModelAnthropicClaudeOpus4, + // bedrock.ModelAnthropicClaudeOpus4, // Model is deprecated bedrock.ModelAnthropicClaudeSonnet4, - bedrock.ModelAnthropicClaude37Sonnet, + // bedrock.ModelAnthropicClaude37Sonnet, // Model is deprecated + bedrock.ModelDeepSeekR1V1, + bedrock.ModelOpenAIGptOss120BV1, + bedrock.ModelOpenAIGptOss20BV1, + bedrock.ModelMoonshotKimiK2Thinking, } for _, model := range reasoningModels { @@ -1024,12 +1140,18 @@ func TestAmazonReasoningStreamingConverseAPI(t *testing.T) { } streamingReasoningModels := []string{ + bedrock.ModelAnthropicClaudeOpus46, + bedrock.ModelAnthropicClaudeSonnet46, bedrock.ModelAnthropicClaudeOpus45, + bedrock.ModelAnthropicClaudeHaiku45, bedrock.ModelAnthropicClaudeSonnet45, - bedrock.ModelAnthropicClaudeOpus41, - bedrock.ModelAnthropicClaudeOpus4, + // bedrock.ModelAnthropicClaudeOpus4, // Model is deprecated bedrock.ModelAnthropicClaudeSonnet4, - bedrock.ModelAnthropicClaude37Sonnet, + // bedrock.ModelAnthropicClaude37Sonnet, // Model is deprecated + bedrock.ModelDeepSeekR1V1, + bedrock.ModelOpenAIGptOss120BV1, + bedrock.ModelOpenAIGptOss20BV1, + bedrock.ModelMoonshotKimiK2Thinking, } for _, model := range streamingReasoningModels { @@ -1374,3 +1496,1395 @@ func testToolCallingWorkflow( t.Logf("Tool calling workflow completed successfully for model: %s", model) return nil } + +// TestAmazonTextResponseWithThinkingConverseAPI tests text response with thinking using Converse API +func TestAmazonTextResponseWithThinkingConverseAPI(t *testing.T) { + ctx := t.Context() + + httprr.SkipIfNoCredentialsAndRecordingMissing(t, "AWS_ACCESS_KEY_ID") + + rr := httprr.OpenForTest(t, http.DefaultTransport) + defer rr.Close() + + if !rr.Recording() { + t.Parallel() + } + + client, err := setUpTestWithTransport(rr) + if err != nil { + t.Fatal(err) + } + llm, err := bedrock.New(bedrock.WithClient(client), bedrock.WithConverseAPI()) + if err != nil { + t.Fatal(err) + } + + messages := []llms.MessageContent{ + { + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{ + llms.TextPart("Solve: If x + 5 = 12, what is x?"), + }, + }, + } + + // Request with thinking + resp, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithReasoning(llms.ReasoningMedium, 2048), + llms.WithMaxTokens(4096), + llms.WithTemperature(1.0), + ) + if err != nil { + t.Fatal(err) + } + + choice := resp.Choices[0] + if choice.Reasoning == nil { + t.Fatal("Expected reasoning in response") + } + if choice.Reasoning.Content == "" { + t.Error("Expected non-empty reasoning content") + } + if len(choice.Reasoning.Signature) == 0 { + t.Error("Expected signature in reasoning") + } + if !strings.Contains(choice.Content, "7") { + t.Errorf("Expected answer '7' in content, got: %s", choice.Content) + } + + // ROUNDTRIP: Continue conversation with preserved signature + messages = append(messages, + llms.MessageContent{ + Role: llms.ChatMessageTypeAI, + Parts: []llms.ContentPart{ + llms.TextPartWithReasoning(choice.Content, choice.Reasoning), + }, + }, + llms.MessageContent{ + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{llms.TextPart("Now solve x + 10 = 25")}, + }, + ) + + resp2, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithReasoning(llms.ReasoningMedium, 2048), + llms.WithMaxTokens(4096), + llms.WithTemperature(1.0), + ) + if err != nil { + t.Fatal(err) + } + if !strings.Contains(resp2.Choices[0].Content, "15") { + t.Errorf("Expected answer '15' in roundtrip response, got: %s", resp2.Choices[0].Content) + } +} + +// TestAmazonTextResponseWithThinkingLegacyAPI tests text response with thinking using Legacy API +func TestAmazonTextResponseWithThinkingLegacyAPI(t *testing.T) { + ctx := t.Context() + + httprr.SkipIfNoCredentialsAndRecordingMissing(t, "AWS_ACCESS_KEY_ID") + + rr := httprr.OpenForTest(t, http.DefaultTransport) + defer rr.Close() + + if !rr.Recording() { + t.Parallel() + } + + client, err := setUpTestWithTransport(rr) + if err != nil { + t.Fatal(err) + } + llm, err := bedrock.New(bedrock.WithClient(client)) // Use Legacy API + if err != nil { + t.Fatal(err) + } + + messages := []llms.MessageContent{ + { + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{ + llms.TextPart("Solve: If x + 5 = 12, what is x?"), + }, + }, + } + + // Request with thinking + resp, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithReasoning(llms.ReasoningMedium, 2048), + llms.WithMaxTokens(4096), + llms.WithTemperature(1.0), + ) + if err != nil { + t.Fatal(err) + } + + choice := resp.Choices[0] + if choice.Reasoning == nil { + t.Fatal("Expected reasoning in response") + } + if choice.Reasoning.Content == "" { + t.Error("Expected non-empty reasoning content") + } + if len(choice.Reasoning.Signature) == 0 { + t.Error("Expected signature in reasoning") + } + if !strings.Contains(choice.Content, "7") { + t.Errorf("Expected answer '7' in content, got: %s", choice.Content) + } + + // ROUNDTRIP: Continue conversation with preserved signature + messages = append(messages, + llms.MessageContent{ + Role: llms.ChatMessageTypeAI, + Parts: []llms.ContentPart{ + llms.TextPartWithReasoning(choice.Content, choice.Reasoning), + }, + }, + llms.MessageContent{ + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{llms.TextPart("Now solve x + 10 = 25")}, + }, + ) + + resp2, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithReasoning(llms.ReasoningMedium, 2048), + llms.WithMaxTokens(4096), + llms.WithTemperature(1.0), + ) + if err != nil { + t.Fatal(err) + } + if !strings.Contains(resp2.Choices[0].Content, "15") { + t.Errorf("Expected answer '15' in roundtrip response, got: %s", resp2.Choices[0].Content) + } +} + +// TestAmazonSingleToolCallWithThinkingConverseAPI tests single tool call with thinking +func TestAmazonSingleToolCallWithThinkingConverseAPI(t *testing.T) { + ctx := t.Context() + + httprr.SkipIfNoCredentialsAndRecordingMissing(t, "AWS_ACCESS_KEY_ID") + + rr := httprr.OpenForTest(t, http.DefaultTransport) + defer rr.Close() + + if !rr.Recording() { + t.Parallel() + } + + client, err := setUpTestWithTransport(rr) + if err != nil { + t.Fatal(err) + } + llm, err := bedrock.New(bedrock.WithClient(client), bedrock.WithConverseAPI()) + if err != nil { + t.Fatal(err) + } + + tools := []llms.Tool{{ + Type: "function", + Function: &llms.FunctionDefinition{ + Name: "get_weather", + Description: "Get weather for a location", + Parameters: map[string]any{ + "type": "object", + "properties": map[string]any{ + "location": map[string]any{"type": "string"}, + }, + "required": []string{"location"}, + }, + }, + }} + + messages := []llms.MessageContent{ + { + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{llms.TextPart("What's the weather in Boston?")}, + }, + } + + resp, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithTools(tools), + llms.WithReasoning(llms.ReasoningMedium, 2048), + llms.WithMaxTokens(4096), + llms.WithTemperature(1.0), + ) + if err != nil { + t.Fatal(err) + } + + if len(resp.Choices[0].ToolCalls) == 0 { + t.Fatal("Expected tool call in response") + } + + choice := resp.Choices[0] + if choice.Reasoning == nil { + t.Error("Expected reasoning in response") + } + if choice.Reasoning != nil && len(choice.Reasoning.Signature) == 0 { + t.Error("Expected signature in reasoning") + } + + // ROUNDTRIP: Send response back preserving reasoning + messages = append(messages, + llms.MessageContent{ + Role: llms.ChatMessageTypeAI, + Parts: []llms.ContentPart{ + llms.TextPartWithReasoning(choice.Content, choice.Reasoning), + resp.Choices[0].ToolCalls[0], + }, + }, + llms.MessageContent{ + Role: llms.ChatMessageTypeTool, + Parts: []llms.ContentPart{ + llms.ToolCallResponse{ + ToolCallID: resp.Choices[0].ToolCalls[0].ID, + Name: resp.Choices[0].ToolCalls[0].FunctionCall.Name, + Content: `{"temperature": 72, "condition": "sunny"}`, + }, + }, + }, + ) + + resp2, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithTools(tools), + llms.WithReasoning(llms.ReasoningMedium, 2048), + llms.WithMaxTokens(4096), + llms.WithTemperature(1.0), + ) + if err != nil { + t.Fatal(err) + } + if !strings.Contains(resp2.Choices[0].Content, "72") { + t.Logf("Expected '72' in final response, got: %s", resp2.Choices[0].Content) + } +} + +// TestAmazonSequentialToolCallsWithThinkingConverseAPI tests sequential tool calls with thinking +func TestAmazonSequentialToolCallsWithThinkingConverseAPI(t *testing.T) { + ctx := t.Context() + + httprr.SkipIfNoCredentialsAndRecordingMissing(t, "AWS_ACCESS_KEY_ID") + + rr := httprr.OpenForTest(t, http.DefaultTransport) + defer rr.Close() + + if !rr.Recording() { + t.Parallel() + } + + client, err := setUpTestWithTransport(rr) + if err != nil { + t.Fatal(err) + } + llm, err := bedrock.New(bedrock.WithClient(client), bedrock.WithConverseAPI()) + if err != nil { + t.Fatal(err) + } + + tools := []llms.Tool{ + { + Type: "function", + Function: &llms.FunctionDefinition{ + Name: "calculate", + Description: "Perform a calculation", + Parameters: map[string]any{ + "type": "object", + "properties": map[string]any{ + "expression": map[string]any{"type": "string"}, + }, + "required": []string{"expression"}, + }, + }, + }, + } + + messages := []llms.MessageContent{ + { + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{ + llms.TextPart("Calculate (5 + 3) and then multiply by 2"), + }, + }, + } + + // First call + resp1, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithTools(tools), + llms.WithReasoning(llms.ReasoningMedium, 2048), + llms.WithMaxTokens(4096), + llms.WithTemperature(1.0), + ) + if err != nil { + t.Fatal(err) + } + if len(resp1.Choices[0].ToolCalls) == 0 { + t.Fatal("Expected tool call in first response") + } + if resp1.Choices[0].Reasoning == nil { + t.Fatal("Expected reasoning in first response") + } + + sig1 := resp1.Choices[0].Reasoning.Signature + + // Execute first tool and continue + choice1 := resp1.Choices[0] + messages = append(messages, + llms.MessageContent{ + Role: llms.ChatMessageTypeAI, + Parts: []llms.ContentPart{ + llms.TextPartWithReasoning(choice1.Content, choice1.Reasoning), + choice1.ToolCalls[0], + }, + }, + llms.MessageContent{ + Role: llms.ChatMessageTypeTool, + Parts: []llms.ContentPart{ + llms.ToolCallResponse{ + ToolCallID: resp1.Choices[0].ToolCalls[0].ID, + Name: resp1.Choices[0].ToolCalls[0].FunctionCall.Name, + Content: "8", + }, + }, + }, + ) + + // Second call + resp2, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithTools(tools), + llms.WithReasoning(llms.ReasoningMedium, 2048), + llms.WithMaxTokens(4096), + llms.WithTemperature(1.0), + ) + if err != nil { + t.Fatal(err) + } + + if resp2.Choices[0].Reasoning != nil { + sig2 := resp2.Choices[0].Reasoning.Signature + + // Signatures should differ (each step has unique context) + if len(sig1) > 0 && len(sig2) > 0 && string(sig1) == string(sig2) { + t.Error("Signatures should differ between turns") + } + } +} + +// TestAmazonTextResponseWithThinkingStreamingConverseAPI tests streaming with thinking +func TestAmazonTextResponseWithThinkingStreamingConverseAPI(t *testing.T) { + ctx := t.Context() + + httprr.SkipIfNoCredentialsAndRecordingMissing(t, "AWS_ACCESS_KEY_ID") + + rr := httprr.OpenForTest(t, http.DefaultTransport) + defer rr.Close() + + if !rr.Recording() { + t.Parallel() + } + + client, err := setUpTestWithTransport(rr) + if err != nil { + t.Fatal(err) + } + llm, err := bedrock.New(bedrock.WithClient(client), bedrock.WithConverseAPI()) + if err != nil { + t.Fatal(err) + } + + messages := []llms.MessageContent{ + { + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{ + llms.TextPart("What is 5 + 3? Think step by step."), + }, + }, + } + + var streamedReasoning []string + var streamedText []string + + streamFunc := llms.WithStreamingFunc(func(ctx context.Context, chunk streaming.Chunk) error { + switch chunk.Type { + case streaming.ChunkTypeReasoning: + if chunk.Reasoning != nil { + streamedReasoning = append(streamedReasoning, chunk.Reasoning.Content) + } + case streaming.ChunkTypeText: + streamedText = append(streamedText, chunk.Content) + default: + } + return nil + }) + + resp, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithReasoning(llms.ReasoningMedium, 2048), + streamFunc, + llms.WithMaxTokens(4096), + llms.WithTemperature(1.0), + ) + if err != nil { + t.Fatal(err) + } + + // Verify accumulated content matches final response + if strings.Join(streamedText, "") != resp.Choices[0].Content { + t.Errorf("Streamed text doesn't match final response") + } + if len(streamedReasoning) > 0 { + accumulatedReasoning := strings.Join(streamedReasoning, "") + if resp.Choices[0].Reasoning != nil && accumulatedReasoning != resp.Choices[0].Reasoning.Content { + t.Errorf("Streamed reasoning doesn't match final response") + } + } + if resp.Choices[0].Reasoning != nil && len(resp.Choices[0].Reasoning.Signature) == 0 { + t.Error("Expected signature in final reasoning") + } +} + +// TestAmazonMultiTurnCachingWithToolsLegacyAPI tests prompt caching across multi-turn conversation with tools. +// This validates that caching works correctly for AI agent workflows using Legacy API. +// +// Expected behavior: +// Turn 1: CacheCreation > 0 (conversation history cached) +// Turn 2: CacheRead > 0 (previous turn read from cache), new content added to cache +// Turn 3+: Cache continues to be used and extended +func TestAmazonMultiTurnCachingWithToolsLegacyAPI(t *testing.T) { + ctx := t.Context() + + httprr.SkipIfNoCredentialsAndRecordingMissing(t, "AWS_ACCESS_KEY_ID") + + rr := httprr.OpenForTest(t, http.DefaultTransport) + defer rr.Close() + + if !rr.Recording() { + t.Parallel() + } + + client, err := setUpTestWithTransport(rr) + if err != nil { + t.Fatal(err) + } + // Use Legacy API for cache_control support + llm, err := bedrock.New(bedrock.WithClient(client)) + if err != nil { + t.Fatal(err) + } + + // Define tools for AI agent + tools := []llms.Tool{ + { + Type: "function", + Function: &llms.FunctionDefinition{ + Name: "get_weather", + Description: "BedrockCacheTest-v1: " + strings.Repeat("Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. ", 30), + Parameters: map[string]any{ + "type": "object", + "properties": map[string]any{ + "location": map[string]any{ + "type": "string", + "description": "City and state, e.g. San Francisco, CA", + }, + }, + "required": []string{"location"}, + }, + }, + }, + { + Type: "function", + Function: &llms.FunctionDefinition{ + Name: "book_flight", + Description: "BedrockCacheTest-v1: " + strings.Repeat("Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. ", 30), + Parameters: map[string]any{ + "type": "object", + "properties": map[string]any{ + "destination": map[string]any{"type": "string", "description": "Destination city"}, + "date": map[string]any{"type": "string", "description": "Departure date"}, + }, + "required": []string{"destination", "date"}, + }, + }, + }, + } + + // Add system prompt to ensure sufficient tokens for caching + systemPrompt := "BedrockCacheTest-v1: " + strings.Repeat("You are a helpful assistant with access to weather and flight booking capabilities. ", 15) + + // Turn 1: Initial request with system prompt + messages := []llms.MessageContent{ + { + Role: llms.ChatMessageTypeSystem, + Parts: []llms.ContentPart{llms.TextPart(systemPrompt)}, + }, + { + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{llms.TextPart("What's the weather in Boston?")}, + }, + } + + resp1, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithTools(tools), + llms.WithMaxTokens(512), + ) + if err != nil { + t.Fatal(err) + } + + if len(resp1.Choices[0].ToolCalls) == 0 { + t.Fatal("Expected tool call in first response") + } + + // Turn 2: Add tool result - mark with cache control for conversation history caching + choice1 := resp1.Choices[0] + messages = append(messages, + llms.MessageContent{ + Role: llms.ChatMessageTypeAI, + Parts: []llms.ContentPart{choice1.ToolCalls[0]}, + }, + llms.MessageContent{ + Role: llms.ChatMessageTypeTool, + Parts: []llms.ContentPart{ + llms.ToolCallResponse{ + ToolCallID: choice1.ToolCalls[0].ID, + Name: choice1.ToolCalls[0].FunctionCall.Name, + Content: `{"temperature": 72, "condition": "sunny"}`, + }, + }, + }, + ) + + resp2, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithTools(tools), + llms.WithMaxTokens(512), + ) + if err != nil { + t.Fatal(err) + } + + t.Logf("Turn 2 Response: %s", resp2.Choices[0].Content) + if !strings.Contains(resp2.Choices[0].Content, "72") && !strings.Contains(resp2.Choices[0].Content, "sunny") { + t.Logf("Turn 2 might not contain weather info: %s", resp2.Choices[0].Content) + } + + // Turn 3: Continue conversation with cached previous context + messages = append(messages, + llms.MessageContent{ + Role: llms.ChatMessageTypeAI, + Parts: []llms.ContentPart{ + bedrock.WithCacheControl( + llms.TextPart(resp2.Choices[0].Content), + bedrock.EphemeralCache(), + ), + }, + }, + llms.MessageContent{ + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{llms.TextPart("Now book a flight to Boston for tomorrow")}, + }, + ) + + resp3, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithTools(tools), + llms.WithMaxTokens(512), + ) + if err != nil { + t.Fatal(err) + } + + t.Logf("Turn 3 Response: %s", resp3.Choices[0].Content) + + // Helper function to extract cache metrics + getCacheMetric := func(resp *llms.ContentResponse, key string) int { + if resp.Choices[0].GenerationInfo != nil { + if val, ok := resp.Choices[0].GenerationInfo[key]; ok { + switch v := val.(type) { + case int: + return v + case int32: + return int(v) + case int64: + return int(v) + } + } + } + return 0 + } + + // Log cache metrics for all turns + t.Logf("Turn 1 - CacheCreation: %d, CacheRead: %d", + getCacheMetric(resp1, "CacheCreationInputTokens"), + getCacheMetric(resp1, "CacheReadInputTokens")) + t.Logf("Turn 2 - CacheCreation: %d, CacheRead: %d", + getCacheMetric(resp2, "CacheCreationInputTokens"), + getCacheMetric(resp2, "CacheReadInputTokens")) + t.Logf("Turn 3 - CacheCreation: %d, CacheRead: %d", + getCacheMetric(resp3, "CacheCreationInputTokens"), + getCacheMetric(resp3, "CacheReadInputTokens")) + + // Verify that cache was created in Turn 3 (due to cache_control on assistant message) + cacheCreation3 := getCacheMetric(resp3, "CacheCreationInputTokens") + if cacheCreation3 > 0 { + t.Logf("✓ Cache successfully created in Turn 3: %d tokens", cacheCreation3) + } else { + t.Logf("Cache creation: %d (may be 0 if context < 1024 tokens)", cacheCreation3) + } + + // Turn 4: Continue conversation - cache should be read from previous turn + messages = append(messages, + llms.MessageContent{ + Role: llms.ChatMessageTypeAI, + Parts: []llms.ContentPart{ + bedrock.WithCacheControl( + llms.TextPart(resp3.Choices[0].Content), + bedrock.EphemeralCache(), + ), + }, + }, + llms.MessageContent{ + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{llms.TextPart("I'm flying from New York on March 4th")}, + }, + ) + + resp4, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithTools(tools), + llms.WithMaxTokens(512), + ) + if err != nil { + t.Fatal(err) + } + + t.Logf("Turn 4 Response: %s", resp4.Choices[0].Content) + + cacheRead4 := getCacheMetric(resp4, "CacheReadInputTokens") + cacheCreation4 := getCacheMetric(resp4, "CacheCreationInputTokens") + t.Logf("Turn 4 - CacheCreation: %d, CacheRead: %d", cacheCreation4, cacheRead4) + + // Verify cache is being utilized + if cacheRead4 > 0 { + t.Logf("✓ Cache successfully read in Turn 4: %d tokens", cacheRead4) + t.Logf("Cache savings: previous context reused from cache") + } else if cacheCreation4 > 0 { + t.Logf("✓ Additional cache created in Turn 4: %d tokens", cacheCreation4) + } +} + +// TestAmazonMultiTurnCachingWithToolsConverseAPI tests prompt caching with Converse API. +// This validates that caching works correctly for AI agent workflows using Converse API. +// +// Expected behavior: +// Turn 3: CacheCreation > 0 (conversation history with cachePoint) +// Turn 4: CacheRead > 0 (previous context read from cache) +func TestAmazonMultiTurnCachingWithToolsConverseAPI(t *testing.T) { + ctx := t.Context() + + httprr.SkipIfNoCredentialsAndRecordingMissing(t, "AWS_ACCESS_KEY_ID") + + rr := httprr.OpenForTest(t, http.DefaultTransport) + defer rr.Close() + + if !rr.Recording() { + t.Parallel() + } + + client, err := setUpTestWithTransport(rr) + if err != nil { + t.Fatal(err) + } + // Use Converse API with cachePoint support + llm, err := bedrock.New(bedrock.WithClient(client), bedrock.WithConverseAPI()) + if err != nil { + t.Fatal(err) + } + + // Define tools with long descriptions to exceed 1024 token threshold + tools := []llms.Tool{ + { + Type: "function", + Function: &llms.FunctionDefinition{ + Name: "get_weather", + Description: "BedrockConverseCache-v1: " + strings.Repeat("Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. ", 30), + Parameters: map[string]any{ + "type": "object", + "properties": map[string]any{ + "location": map[string]any{ + "type": "string", + "description": "City and state, e.g. San Francisco, CA", + }, + }, + "required": []string{"location"}, + }, + }, + }, + { + Type: "function", + Function: &llms.FunctionDefinition{ + Name: "book_flight", + Description: "BedrockConverseCache-v1: " + strings.Repeat("Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. ", 30), + Parameters: map[string]any{ + "type": "object", + "properties": map[string]any{ + "destination": map[string]any{"type": "string", "description": "Destination city"}, + "date": map[string]any{"type": "string", "description": "Departure date"}, + }, + "required": []string{"destination", "date"}, + }, + }, + }, + } + + // Add system prompt to ensure sufficient tokens + systemPrompt := "BedrockConverseCache-v1: " + strings.Repeat("You are a helpful assistant with access to weather and flight booking capabilities. ", 15) + + // Turn 1: Initial request with system prompt + messages := []llms.MessageContent{ + { + Role: llms.ChatMessageTypeSystem, + Parts: []llms.ContentPart{llms.TextPart(systemPrompt)}, + }, + { + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{llms.TextPart("What's the weather in Boston?")}, + }, + } + + resp1, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithTools(tools), + llms.WithMaxTokens(512), + ) + if err != nil { + t.Fatal(err) + } + + if len(resp1.Choices[0].ToolCalls) == 0 { + t.Fatal("Expected tool call in first response") + } + + // Turn 2: Add tool result + choice1 := resp1.Choices[0] + messages = append(messages, + llms.MessageContent{ + Role: llms.ChatMessageTypeAI, + Parts: []llms.ContentPart{choice1.ToolCalls[0]}, + }, + llms.MessageContent{ + Role: llms.ChatMessageTypeTool, + Parts: []llms.ContentPart{ + llms.ToolCallResponse{ + ToolCallID: choice1.ToolCalls[0].ID, + Name: choice1.ToolCalls[0].FunctionCall.Name, + Content: `{"temperature": 72, "condition": "sunny"}`, + }, + }, + }, + ) + + resp2, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithTools(tools), + llms.WithMaxTokens(512), + ) + if err != nil { + t.Fatal(err) + } + + t.Logf("Turn 2 Response: %s", resp2.Choices[0].Content) + + // Turn 3: Continue conversation with cachePoint (mark assistant response for caching) + messages = append(messages, + llms.MessageContent{ + Role: llms.ChatMessageTypeAI, + Parts: []llms.ContentPart{ + bedrock.WithCacheControl( + llms.TextPart(resp2.Choices[0].Content), + bedrock.EphemeralCache(), + ), + }, + }, + llms.MessageContent{ + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{llms.TextPart("Now book a flight to Boston for tomorrow")}, + }, + ) + + resp3, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithTools(tools), + llms.WithMaxTokens(512), + ) + if err != nil { + t.Fatal(err) + } + + t.Logf("Turn 3 Response: %s", resp3.Choices[0].Content) + + // Turn 4: Continue conversation - cache should be read + choice3 := resp3.Choices[0] + var turn4Parts []llms.ContentPart + if len(choice3.ToolCalls) > 0 { + turn4Parts = append(turn4Parts, choice3.ToolCalls[0]) + } else { + turn4Parts = append(turn4Parts, bedrock.WithCacheControl( + llms.TextPart(choice3.Content), + bedrock.EphemeralCache(), + )) + } + + messages = append(messages, + llms.MessageContent{ + Role: llms.ChatMessageTypeAI, + Parts: turn4Parts, + }, + llms.MessageContent{ + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{llms.TextPart("I'm flying from New York on March 4th")}, + }, + ) + + resp4, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithTools(tools), + llms.WithMaxTokens(512), + ) + if err != nil { + t.Fatal(err) + } + + t.Logf("Turn 4 Response: %s", resp4.Choices[0].Content) + + // Helper function to extract cache metrics + getCacheMetric := func(resp *llms.ContentResponse, key string) int { + if resp.Choices[0].GenerationInfo != nil { + if val, ok := resp.Choices[0].GenerationInfo[key]; ok { + switch v := val.(type) { + case int: + return v + case int32: + return int(v) + case int64: + return int(v) + } + } + } + return 0 + } + + // Log cache metrics for all turns + t.Logf("Turn 1 - CacheCreation: %d, CacheRead: %d", + getCacheMetric(resp1, "CacheCreationInputTokens"), + getCacheMetric(resp1, "CacheReadInputTokens")) + t.Logf("Turn 2 - CacheCreation: %d, CacheRead: %d", + getCacheMetric(resp2, "CacheCreationInputTokens"), + getCacheMetric(resp2, "CacheReadInputTokens")) + t.Logf("Turn 3 - CacheCreation: %d, CacheRead: %d", + getCacheMetric(resp3, "CacheCreationInputTokens"), + getCacheMetric(resp3, "CacheReadInputTokens")) + t.Logf("Turn 4 - CacheCreation: %d, CacheRead: %d", + getCacheMetric(resp4, "CacheCreationInputTokens"), + getCacheMetric(resp4, "CacheReadInputTokens")) + + // Verify caching behavior + cacheRead4 := getCacheMetric(resp4, "CacheReadInputTokens") + cacheCreation3 := getCacheMetric(resp3, "CacheCreationInputTokens") + + if cacheRead4 > 0 { + t.Logf("✓ Cache successfully read in Turn 4: %d tokens", cacheRead4) + } + if cacheCreation3 > 0 { + t.Logf("✓ Cache successfully created in Turn 3: %d tokens", cacheCreation3) + } +} + +// TestAmazonAutomaticCachingLegacyAPI tests automatic prompt caching without manual cache control. +// This validates that WithAutomaticCaching() works correctly with Legacy API. +// +// Expected behavior: +// - Cache points are automatically added to conversation history +// - No manual bedrock.WithCacheControl() wrapper needed +// - Cache metrics show cache utilization +func TestAmazonAutomaticCachingLegacyAPI(t *testing.T) { + ctx := t.Context() + + httprr.SkipIfNoCredentialsAndRecordingMissing(t, "AWS_ACCESS_KEY_ID") + + rr := httprr.OpenForTest(t, http.DefaultTransport) + defer rr.Close() + + if !rr.Recording() { + t.Parallel() + } + + client, err := setUpTestWithTransport(rr) + if err != nil { + t.Fatal(err) + } + // Use Legacy API with automatic caching enabled + llm, err := bedrock.New( + bedrock.WithClient(client), + bedrock.WithAutomaticCaching(), + ) + if err != nil { + t.Fatal(err) + } + + // Define tools with long descriptions to exceed 1024 token threshold + tools := []llms.Tool{ + { + Type: "function", + Function: &llms.FunctionDefinition{ + Name: "get_weather", + Description: "BedrockAutoCacheTest-v1: " + strings.Repeat("Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. ", 30), + Parameters: map[string]any{ + "type": "object", + "properties": map[string]any{ + "location": map[string]any{ + "type": "string", + "description": "City and state, e.g. San Francisco, CA", + }, + }, + "required": []string{"location"}, + }, + }, + }, + } + + // Add system prompt to ensure sufficient tokens + systemPrompt := "BedrockAutoCacheTest-v1: " + strings.Repeat("You are a helpful assistant with access to weather capabilities. ", 15) + + // Turn 1: Initial request with system prompt + messages := []llms.MessageContent{ + { + Role: llms.ChatMessageTypeSystem, + Parts: []llms.ContentPart{llms.TextPart(systemPrompt)}, + }, + { + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{llms.TextPart("What's the weather in Boston?")}, + }, + } + + resp1, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithTools(tools), + llms.WithMaxTokens(512), + ) + if err != nil { + t.Fatal(err) + } + + if len(resp1.Choices[0].ToolCalls) == 0 { + t.Fatal("Expected tool call in first response") + } + + // Turn 2: Add tool result - NO manual cache control needed + choice1 := resp1.Choices[0] + messages = append(messages, + llms.MessageContent{ + Role: llms.ChatMessageTypeAI, + Parts: []llms.ContentPart{choice1.ToolCalls[0]}, + }, + llms.MessageContent{ + Role: llms.ChatMessageTypeTool, + Parts: []llms.ContentPart{ + llms.ToolCallResponse{ + ToolCallID: choice1.ToolCalls[0].ID, + Name: choice1.ToolCalls[0].FunctionCall.Name, + Content: `{"temperature": 72, "condition": "sunny"}`, + }, + }, + }, + ) + + resp2, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithTools(tools), + llms.WithMaxTokens(512), + ) + if err != nil { + t.Fatal(err) + } + + t.Logf("Turn 2 Response: %s", resp2.Choices[0].Content) + + // Turn 3: Continue conversation - automatic caching should apply + messages = append(messages, + llms.MessageContent{ + Role: llms.ChatMessageTypeAI, + Parts: []llms.ContentPart{ + llms.TextPart(resp2.Choices[0].Content), + }, + }, + llms.MessageContent{ + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{llms.TextPart("What about New York?")}, + }, + ) + + resp3, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithTools(tools), + llms.WithMaxTokens(512), + ) + if err != nil { + t.Fatal(err) + } + + t.Logf("Turn 3 Response: %+v", resp3.Choices[0]) + + // Helper function to extract cache metrics + getCacheMetric := func(resp *llms.ContentResponse, key string) int { + if resp.Choices[0].GenerationInfo != nil { + if val, ok := resp.Choices[0].GenerationInfo[key]; ok { + switch v := val.(type) { + case int: + return v + case int32: + return int(v) + case int64: + return int(v) + } + } + } + return 0 + } + + // Log cache metrics for all turns + t.Logf("Turn 1 - CacheCreation: %d, CacheRead: %d", + getCacheMetric(resp1, "CacheCreationInputTokens"), + getCacheMetric(resp1, "CacheReadInputTokens")) + t.Logf("Turn 2 - CacheCreation: %d, CacheRead: %d", + getCacheMetric(resp2, "CacheCreationInputTokens"), + getCacheMetric(resp2, "CacheReadInputTokens")) + t.Logf("Turn 3 - CacheCreation: %d, CacheRead: %d", + getCacheMetric(resp3, "CacheCreationInputTokens"), + getCacheMetric(resp3, "CacheReadInputTokens")) + + // Verify automatic caching is working + cacheCreation3 := getCacheMetric(resp3, "CacheCreationInputTokens") + cacheRead3 := getCacheMetric(resp3, "CacheReadInputTokens") + + if cacheCreation3 > 0 { + t.Logf("✓ Automatic cache successfully created in Turn 3: %d tokens", cacheCreation3) + } + if cacheRead3 > 0 { + t.Logf("✓ Automatic cache successfully read in Turn 3: %d tokens", cacheRead3) + } +} + +// TestAmazonAutomaticCachingConverseAPI tests automatic prompt caching with Converse API. +// This validates that WithAutomaticCaching() works correctly with Converse API. +func TestAmazonAutomaticCachingConverseAPI(t *testing.T) { + ctx := t.Context() + + httprr.SkipIfNoCredentialsAndRecordingMissing(t, "AWS_ACCESS_KEY_ID") + + rr := httprr.OpenForTest(t, http.DefaultTransport) + defer rr.Close() + + if !rr.Recording() { + t.Parallel() + } + + client, err := setUpTestWithTransport(rr) + if err != nil { + t.Fatal(err) + } + // Use Converse API with automatic caching enabled + llm, err := bedrock.New( + bedrock.WithClient(client), + bedrock.WithConverseAPI(), + bedrock.WithAutomaticCaching(), + ) + if err != nil { + t.Fatal(err) + } + + // Define tools with long descriptions to exceed 1024 token threshold + tools := []llms.Tool{ + { + Type: "function", + Function: &llms.FunctionDefinition{ + Name: "get_weather", + Description: "BedrockConverseAutoCacheTest-v1: " + strings.Repeat("Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. ", 30), + Parameters: map[string]any{ + "type": "object", + "properties": map[string]any{ + "location": map[string]any{ + "type": "string", + "description": "City and state, e.g. San Francisco, CA", + }, + }, + "required": []string{"location"}, + }, + }, + }, + } + + // Add system prompt to ensure sufficient tokens + systemPrompt := "BedrockConverseAutoCacheTest-v1: " + strings.Repeat("You are a helpful assistant with access to weather capabilities. ", 15) + + // Turn 1: Initial request with system prompt + messages := []llms.MessageContent{ + { + Role: llms.ChatMessageTypeSystem, + Parts: []llms.ContentPart{llms.TextPart(systemPrompt)}, + }, + { + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{llms.TextPart("What's the weather in Boston?")}, + }, + } + + resp1, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithTools(tools), + llms.WithMaxTokens(512), + ) + if err != nil { + t.Fatal(err) + } + + if len(resp1.Choices[0].ToolCalls) == 0 { + t.Fatal("Expected tool call in first response") + } + + // Turn 2: Add tool result - NO manual cache control needed + choice1 := resp1.Choices[0] + messages = append(messages, + llms.MessageContent{ + Role: llms.ChatMessageTypeAI, + Parts: []llms.ContentPart{choice1.ToolCalls[0]}, + }, + llms.MessageContent{ + Role: llms.ChatMessageTypeTool, + Parts: []llms.ContentPart{ + llms.ToolCallResponse{ + ToolCallID: choice1.ToolCalls[0].ID, + Name: choice1.ToolCalls[0].FunctionCall.Name, + Content: `{"temperature": 72, "condition": "sunny"}`, + }, + }, + }, + ) + + resp2, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithTools(tools), + llms.WithMaxTokens(512), + ) + if err != nil { + t.Fatal(err) + } + + t.Logf("Turn 2 Response: %s", resp2.Choices[0].Content) + + // Turn 3: Continue conversation - automatic caching should apply + messages = append(messages, + llms.MessageContent{ + Role: llms.ChatMessageTypeAI, + Parts: []llms.ContentPart{ + llms.TextPart(resp2.Choices[0].Content), + }, + }, + llms.MessageContent{ + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{llms.TextPart("What about New York?")}, + }, + ) + + resp3, err := llm.GenerateContent(ctx, messages, + llms.WithModel(bedrock.ModelAnthropicClaudeSonnet45), + llms.WithTools(tools), + llms.WithMaxTokens(512), + ) + if err != nil { + t.Fatal(err) + } + + t.Logf("Turn 3 Response: %+v", resp3.Choices[0]) + + // Helper function to extract cache metrics + getCacheMetric := func(resp *llms.ContentResponse, key string) int { + if resp.Choices[0].GenerationInfo != nil { + if val, ok := resp.Choices[0].GenerationInfo[key]; ok { + switch v := val.(type) { + case int: + return v + case int32: + return int(v) + case int64: + return int(v) + } + } + } + return 0 + } + + // Log cache metrics for all turns + t.Logf("Turn 1 - CacheCreation: %d, CacheRead: %d", + getCacheMetric(resp1, "CacheCreationInputTokens"), + getCacheMetric(resp1, "CacheReadInputTokens")) + t.Logf("Turn 2 - CacheCreation: %d, CacheRead: %d", + getCacheMetric(resp2, "CacheCreationInputTokens"), + getCacheMetric(resp2, "CacheReadInputTokens")) + t.Logf("Turn 3 - CacheCreation: %d, CacheRead: %d", + getCacheMetric(resp3, "CacheCreationInputTokens"), + getCacheMetric(resp3, "CacheReadInputTokens")) + + // Verify automatic caching is working + cacheCreation3 := getCacheMetric(resp3, "CacheCreationInputTokens") + cacheRead3 := getCacheMetric(resp3, "CacheReadInputTokens") + + if cacheCreation3 > 0 { + t.Logf("✓ Automatic cache successfully created in Turn 3: %d tokens", cacheCreation3) + } + if cacheRead3 > 0 { + t.Logf("✓ Automatic cache successfully read in Turn 3: %d tokens", cacheRead3) + } +} + +// TestCreateClientWithLongLeavingCredentials tests creating a client with long leaving credentials. +func TestCreateClientWithLongLeavingCredentials(t *testing.T) { + ctx := t.Context() + + httprr.SkipIfNoCredentialsAndRecordingMissing(t, "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_REGION") + + rr := httprr.OpenForTest(t, http.DefaultTransport) + defer rr.Close() + + if !rr.Recording() { + t.Parallel() + } + + // Configure request scrubbing to remove dynamic AWS headers + rr.ScrubReq(func(req *http.Request) error { + req.Header.Del("Amz-Sdk-Invocation-Id") + req.Header.Del("Amz-Sdk-Request") + req.Header.Del("X-Amz-Date") + req.Header.Del("Authorization") // AWS Signature V4 is unique per request + return nil + }) + + httpClient := &http.Client{ + Transport: rr, + } + + region := os.Getenv("AWS_REGION") + accessKey := os.Getenv("AWS_ACCESS_KEY_ID") + secretKey := os.Getenv("AWS_SECRET_ACCESS_KEY") + sessionToken := os.Getenv("AWS_SESSION_TOKEN") + + opts := []func(*config.LoadOptions) error{ + config.WithHTTPClient(httpClient), + config.WithRegion(region), + config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider( + accessKey, + secretKey, + sessionToken, + )), + } + + cfg, err := config.LoadDefaultConfig(ctx, opts...) + if err != nil { + t.Fatal(err) + } + + client := bedrockruntime.NewFromConfig(cfg) + + llm, err := bedrock.New(bedrock.WithClient(client), bedrock.WithConverseAPI()) + if err != nil { + t.Fatal(err) + } + + model := bedrock.ModelAnthropicClaudeSonnet45 + resp, err := llm.Call(ctx, "Hello, how are you?", llms.WithModel(model), llms.WithMaxTokens(512)) + if err != nil { + t.Fatal(err) + } + + if resp == "" { + t.Fatal("Expected non-empty response") + } + + t.Logf("Response: %s", resp) +} + +// TestCreateClientWithBearerTokenCredentials tests creating a client with bearer token credentials. +func TestCreateClientWithBearerTokenCredentials(t *testing.T) { + ctx := t.Context() + + httprr.SkipIfNoCredentialsAndRecordingMissing(t, "AWS_BEDROCK_BEARER_TOKEN", "AWS_REGION") + + rr := httprr.OpenForTest(t, http.DefaultTransport) + defer rr.Close() + + if !rr.Recording() { + t.Parallel() + } + + // Configure request scrubbing to remove dynamic AWS headers + rr.ScrubReq(func(req *http.Request) error { + req.Header.Del("Amz-Sdk-Invocation-Id") + req.Header.Del("Amz-Sdk-Request") + req.Header.Del("X-Amz-Date") + req.Header.Del("Authorization") + return nil + }) + + httpClient := &http.Client{ + Transport: rr, + } + + region := os.Getenv("AWS_REGION") + bearerToken := os.Getenv("AWS_BEDROCK_BEARER_TOKEN") + + opts := []func(*config.LoadOptions) error{ + config.WithHTTPClient(httpClient), + config.WithRegion(region), + config.WithBearerAuthTokenProvider(bearer.StaticTokenProvider{ + Token: bearer.Token{ + Value: bearerToken, + }, + }), + } + + cfg, err := config.LoadDefaultConfig(ctx, opts...) + if err != nil { + t.Fatal(err) + } + + client := bedrockruntime.NewFromConfig(cfg) + + llm, err := bedrock.New(bedrock.WithClient(client), bedrock.WithConverseAPI()) + if err != nil { + t.Fatal(err) + } + + model := bedrock.ModelAnthropicClaudeSonnet45 + resp, err := llm.Call(ctx, "Hello, how are you?", llms.WithModel(model), llms.WithMaxTokens(512)) + if err != nil { + t.Fatal(err) + } + + if resp == "" { + t.Fatal("Expected non-empty response") + } + + t.Logf("Response: %s", resp) +} diff --git a/llms/bedrock/bedrockllm_unit_test.go b/llms/bedrock/bedrockllm_unit_test.go index 19b45496..04f40102 100644 --- a/llms/bedrock/bedrockllm_unit_test.go +++ b/llms/bedrock/bedrockllm_unit_test.go @@ -177,6 +177,14 @@ func TestOptions(t *testing.T) { t.Error("WithConverseAPI() did not enable Converse API") } }) + + t.Run("WithAutomaticCaching", func(t *testing.T) { + opts := &options{} + WithAutomaticCaching()(opts) + if !opts.enableAutoCaching { + t.Error("WithAutomaticCaching() did not enable automatic caching") + } + }) } func TestModelConstants(t *testing.T) { @@ -189,6 +197,8 @@ func TestModelConstants(t *testing.T) { ModelAmazonNovaProV1, ModelAmazonNovaLiteV1, ModelAmazonNovaMicroV1, + ModelAnthropicClaudeOpus46, + ModelAnthropicClaudeSonnet46, ModelAnthropicClaudeOpus45, ModelAnthropicClaudeHaiku45, ModelAnthropicClaudeSonnet45, @@ -248,3 +258,260 @@ func (h *testCallbackHandler) HandleRetrieverStart(ctx context.Context, query st func (h *testCallbackHandler) HandleRetrieverEnd(ctx context.Context, query string, documents []schema.Document) { } func (h *testCallbackHandler) HandleStreamingFunc(ctx context.Context, chunk streaming.Chunk) {} + +// TestSupportsCaching tests the supportsCaching method +func TestSupportsCaching(t *testing.T) { + llm := &LLM{} + + tests := []struct { + name string + modelID string + expected bool + }{ + { + name: "Claude Opus 4.6 supports caching", + modelID: ModelAnthropicClaudeOpus46, + expected: true, + }, + { + name: "Claude Sonnet 4.6 supports caching", + modelID: ModelAnthropicClaudeSonnet46, + expected: true, + }, + { + name: "Claude Opus 4.5 supports caching", + modelID: ModelAnthropicClaudeOpus45, + expected: true, + }, + { + name: "Claude Haiku 4.5 supports caching", + modelID: ModelAnthropicClaudeHaiku45, + expected: true, + }, + { + name: "Claude Sonnet 4.5 supports caching", + modelID: ModelAnthropicClaudeSonnet45, + expected: true, + }, + { + name: "Claude Opus 4.1 supports caching", + modelID: ModelAnthropicClaudeOpus41, + expected: true, + }, + { + name: "Claude Opus 4 supports caching", + modelID: ModelAnthropicClaudeOpus4, + expected: true, + }, + { + name: "Claude Sonnet 4 supports caching", + modelID: ModelAnthropicClaudeSonnet4, + expected: true, + }, + { + name: "Claude 3.7 Sonnet does not support caching", + modelID: ModelAnthropicClaude37Sonnet, + expected: false, + }, + { + name: "Claude 3.5 Haiku does not support caching", + modelID: ModelAnthropicClaude35Haiku, + expected: false, + }, + { + name: "Amazon Nova does not support caching", + modelID: ModelAmazonNovaProV1, + expected: false, + }, + { + name: "Meta Llama does not support caching", + modelID: ModelMetaLlama3370bInstructV1, + expected: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := llm.supportsCaching(tt.modelID) + if result != tt.expected { + t.Errorf("supportsCaching(%s) = %v, want %v", tt.modelID, result, tt.expected) + } + }) + } +} + +// TestApplyAutomaticCaching tests the applyAutomaticCaching function +func TestApplyAutomaticCaching(t *testing.T) { + tests := []struct { + name string + messages []bedrockclient.Message + expectedCacheIdx int + expectNoCaching bool + }{ + { + name: "cache applied to last assistant message", + messages: []bedrockclient.Message{ + {Role: llms.ChatMessageTypeHuman, Type: "text", Content: "Hello"}, + {Role: llms.ChatMessageTypeAI, Type: "text", Content: "Hi there"}, + {Role: llms.ChatMessageTypeHuman, Type: "text", Content: "How are you?"}, + }, + expectedCacheIdx: 1, + }, + { + name: "cache applied to tool result before human message", + messages: []bedrockclient.Message{ + {Role: llms.ChatMessageTypeHuman, Type: "text", Content: "What's the weather?"}, + {Role: llms.ChatMessageTypeAI, Type: "tool_use"}, + {Role: llms.ChatMessageTypeTool, Type: "tool_result", Content: "72F"}, + {Role: llms.ChatMessageTypeHuman, Type: "text", Content: "Thanks"}, + }, + expectedCacheIdx: 2, + }, + { + name: "no caching for single human message", + messages: []bedrockclient.Message{ + {Role: llms.ChatMessageTypeHuman, Type: "text", Content: "Hello"}, + }, + expectNoCaching: true, + }, + { + name: "no caching when last message is system", + messages: []bedrockclient.Message{ + {Role: llms.ChatMessageTypeSystem, Type: "text", Content: "You are helpful"}, + }, + expectNoCaching: true, + }, + { + name: "cache applied to assistant message before final human", + messages: []bedrockclient.Message{ + {Role: llms.ChatMessageTypeSystem, Type: "text", Content: "System"}, + {Role: llms.ChatMessageTypeHuman, Type: "text", Content: "Hello"}, + {Role: llms.ChatMessageTypeAI, Type: "text", Content: "Hi"}, + {Role: llms.ChatMessageTypeHuman, Type: "text", Content: "Tell me more"}, + }, + expectedCacheIdx: 2, + }, + { + name: "empty messages", + messages: []bedrockclient.Message{}, + expectNoCaching: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Make a copy to avoid modifying test data + messages := make([]bedrockclient.Message, len(tt.messages)) + copy(messages, tt.messages) + + applyAutomaticCaching(messages) + + if tt.expectNoCaching { + // Verify no cache control was added + for i, msg := range messages { + if msg.CacheControl != nil { + t.Errorf("Expected no cache control, but found at index %d", i) + } + } + } else { + // Verify cache control was added to expected message + if messages[tt.expectedCacheIdx].CacheControl == nil { + t.Errorf("Expected cache control at index %d, but not found", tt.expectedCacheIdx) + } else { + if messages[tt.expectedCacheIdx].CacheControl.Type != "ephemeral" { + t.Errorf("Expected cache type 'ephemeral', got '%s'", messages[tt.expectedCacheIdx].CacheControl.Type) + } + if messages[tt.expectedCacheIdx].CacheControl.TTL != "5m" { + t.Errorf("Expected TTL '5m', got '%s'", messages[tt.expectedCacheIdx].CacheControl.TTL) + } + } + + // Verify no other messages have cache control + for i := range messages { + if i != tt.expectedCacheIdx && messages[i].CacheControl != nil { + t.Errorf("Unexpected cache control at index %d (expected only at %d)", i, tt.expectedCacheIdx) + } + } + } + }) + } +} + +// TestProcessMessagesWithCaching tests the processMessagesWithCaching function +func TestProcessMessagesWithCaching(t *testing.T) { + tests := []struct { + name string + messages []llms.MessageContent + autoCaching bool + expectCache bool + cacheAtIndex int + }{ + { + name: "automatic caching enabled", + messages: []llms.MessageContent{ + { + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{ + llms.TextContent{Text: "Hello"}, + }, + }, + { + Role: llms.ChatMessageTypeAI, + Parts: []llms.ContentPart{ + llms.TextContent{Text: "Hi there"}, + }, + }, + { + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{ + llms.TextContent{Text: "How are you?"}, + }, + }, + }, + autoCaching: true, + expectCache: true, + cacheAtIndex: 1, + }, + { + name: "automatic caching disabled", + messages: []llms.MessageContent{ + { + Role: llms.ChatMessageTypeHuman, + Parts: []llms.ContentPart{ + llms.TextContent{Text: "Hello"}, + }, + }, + { + Role: llms.ChatMessageTypeAI, + Parts: []llms.ContentPart{ + llms.TextContent{Text: "Hi there"}, + }, + }, + }, + autoCaching: false, + expectCache: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := processMessagesWithCaching(tt.messages, tt.autoCaching) + if err != nil { + t.Errorf("processMessagesWithCaching() error = %v", err) + return + } + + if tt.expectCache { + if result[tt.cacheAtIndex].CacheControl == nil { + t.Errorf("Expected cache control at index %d, but not found", tt.cacheAtIndex) + } + } else { + for i, msg := range result { + if msg.CacheControl != nil { + t.Errorf("Unexpected cache control at index %d", i) + } + } + } + }) + } +} diff --git a/llms/bedrock/doc.go b/llms/bedrock/doc.go new file mode 100644 index 00000000..b4c532ca --- /dev/null +++ b/llms/bedrock/doc.go @@ -0,0 +1,208 @@ +// Package bedrock provides AWS Bedrock integration for LangChainGo. +// +// # Overview +// +// This package implements LLM client for AWS Bedrock, supporting multiple model providers +// including Anthropic Claude, Amazon Nova, Meta Llama, Cohere, AI21, and DeepSeek. +// +// # Architecture +// +// The package consists of three layers: +// +// 1. Public API Layer (bedrockllm.go): Exposes bedrock.LLM and bedrock.New() constructor +// 2. Message Processing Layer: Converts llms.MessageContent to provider-specific formats +// 3. Internal Client Layer (internal/bedrockclient): Handles AWS SDK interactions +// +// Two API modes are supported: +// +// - Legacy API: Model-specific implementations via InvokeModel/InvokeModelWithResponseStream +// - Converse API: Unified implementation via Converse/ConverseStream (recommended) +// +// # Basic Usage +// +// Create a Bedrock client: +// +// import "github.com/vxcontrol/langchaingo/llms/bedrock" +// +// llm, err := bedrock.New( +// bedrock.WithModel(bedrock.ModelAnthropicClaudeSonnet45), +// bedrock.WithConverseAPI(), +// ) +// +// Generate content: +// +// messages := []llms.MessageContent{ +// llms.TextParts(llms.ChatMessageTypeHuman, "Hello!"), +// } +// resp, err := llm.GenerateContent(ctx, messages, +// llms.WithMaxTokens(1024), +// ) +// +// # Automatic Prompt Caching +// +// For Claude 4.x models (Opus 4, Sonnet 4, Haiku 4), automatic caching is available: +// +// llm, err := bedrock.New( +// bedrock.WithModel(bedrock.ModelAnthropicClaudeSonnet45), +// bedrock.WithConverseAPI(), +// bedrock.WithAutomaticCaching(), // Enable automatic caching +// ) +// +// When enabled, the client automatically: +// - Detects Claude 4.x models by model ID patterns (anthropic.claude-opus-4, sonnet-4, haiku-4) +// - Adds cache points to the last assistant or tool message before new user input +// - Uses ephemeral 5-minute TTL by default +// - Works transparently without modifying client code +// +// Benefits: +// - 90% cost reduction on cached input tokens +// - No manual cache control wrappers needed +// - Automatic conversation history caching +// +// Manual caching (for fine-grained control): +// +// messages := []llms.MessageContent{ +// { +// Role: llms.ChatMessageTypeAI, +// Parts: []llms.ContentPart{ +// bedrock.WithCacheControl( +// llms.TextPart("long context..."), +// bedrock.EphemeralCache(), +// ), +// }, +// }, +// } +// +// # Tool Calling +// +// Both APIs support tool calling for compatible models: +// +// tools := []llms.Tool{ +// { +// Type: "function", +// Function: &llms.FunctionDefinition{ +// Name: "get_weather", +// Description: "Get weather for location", +// Parameters: map[string]any{...}, +// }, +// }, +// } +// +// resp, err := llm.GenerateContent(ctx, messages, +// llms.WithTools(tools), +// ) +// +// # Reasoning Support +// +// Claude 4.x and 3.7 models support reasoning (thinking) mode: +// +// resp, err := llm.GenerateContent(ctx, messages, +// llms.WithReasoning(llms.ReasoningMedium, 2048), +// ) +// +// // Access reasoning content +// if resp.Choices[0].Reasoning != nil { +// fmt.Println(resp.Choices[0].Reasoning.Content) +// } +// +// # Streaming +// +// Both APIs support streaming responses: +// +// streamFunc := func(ctx context.Context, chunk streaming.Chunk) error { +// switch chunk.Type { +// case streaming.ChunkTypeText: +// fmt.Print(chunk.Content) +// case streaming.ChunkTypeReasoning: +// fmt.Println("Thinking:", chunk.Reasoning.Content) +// case streaming.ChunkTypeToolCall: +// fmt.Println("Tool:", chunk.ToolCall.Name) +// } +// return nil +// } +// +// resp, err := llm.GenerateContent(ctx, messages, +// llms.WithStreamingFunc(streamFunc), +// ) +// +// # Supported Models +// +// See models_list.go for complete list. Major providers: +// +// - Anthropic: Claude 4.6 (Opus, Sonnet), Claude 4.5, 4.1, 4, 3.7, 3.5 +// - Amazon: Nova 2 Lite, Nova Premier, Nova Pro, Nova Lite, Nova Micro +// - Meta: Llama 4, Llama 3.3, 3.2, 3.1, 3 +// - Cohere: Command R, Command R+ +// - AI21: Jamba 1.5 Large, Mini +// - DeepSeek: R1 +// - OpenAI: GPT-OSS-120B, GPT-OSS-20B +// - Qwen: Qwen3 Next, Qwen3 VL, Qwen3 32B, Qwen3 Coder (30B, Next) +// - Mistral: Large 3, Magistral Small +// - Moonshot: Kimi K2.5, Kimi K2 Thinking +// - Z.AI: GLM-4.7, GLM-4.7-Flash +// +// # Error Handling +// +// Provider-specific errors are mapped to standardized error codes: +// +// resp, err := llm.GenerateContent(ctx, messages) +// if err != nil { +// if llmErr, ok := err.(*llms.Error); ok { +// switch llmErr.Code { +// case llms.ErrCodeRateLimit: +// // Handle rate limiting +// case llms.ErrCodeAuthentication: +// // Handle auth errors +// } +// } +// } +// +// See errors.go for complete error mapping. +// +// # AWS Configuration +// +// The client uses AWS SDK v2 configuration: +// +// - Credentials: From environment (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) or AWS config +// - Region: From environment (AWS_REGION) or default config +// - Custom configuration: Use bedrock.WithClient() with pre-configured bedrockruntime.Client +// +// # Performance Considerations +// +// - Converse API is recommended for new applications (unified, better error handling) +// - Automatic caching reduces costs by 90% for cached tokens (Claude 4.x only) +// - Streaming reduces latency for interactive applications +// - Minimum cache checkpoint: 1024 tokens (Sonnet 4.5), 4096 tokens (Haiku 4.5) +// +// # Maintenance +// +// When adding new models: +// 1. Add model constant to models_list.go with documentation +// 2. Update provider detection in internal/bedrockclient/bedrockclient.go if needed +// 3. Add provider-specific implementation in internal/bedrockclient/provider_*.go +// 4. Update tests in bedrockllm_test.go to include new model +// 5. For caching support, add pattern to supportsCaching() method +// +// When updating API: +// 1. Converse API changes go to internal/bedrockclient/bedrockclient_converse.go +// 2. Legacy API changes go to internal/bedrockclient/provider_*.go +// 3. Message processing changes go to bedrockllm.go (processMessages, processMessagesWithCaching) +// 4. Always maintain backward compatibility +// 5. Add integration tests with httprr recording +// +// # Testing +// +// Tests use httprr for HTTP recording/replay: +// +// - Integration tests: bedrockllm_test.go (requires AWS credentials) +// - Unit tests: bedrockllm_unit_test.go (no credentials needed) +// - Tool calling: bedrock_tool_integration_test.go +// +// Recording new HTTP interactions: +// +// HTTPRR_RECORD=. go test -v -run TestName ./llms/bedrock/ +// +// Debug HTTP interactions: +// +// HTTPRR_RECORD=. HTTPRR_DEBUG=true go test -v -run TestName ./llms/bedrock/ +package bedrock diff --git a/llms/bedrock/internal/bedrockclient/bedrockclient.go b/llms/bedrock/internal/bedrockclient/bedrockclient.go index 1070d5ba..301c6498 100644 --- a/llms/bedrock/internal/bedrockclient/bedrockclient.go +++ b/llms/bedrock/internal/bedrockclient/bedrockclient.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/vxcontrol/langchaingo/llms" + "github.com/vxcontrol/langchaingo/llms/reasoning" "github.com/aws/aws-sdk-go-v2/service/bedrockruntime" ) @@ -31,6 +32,16 @@ type Message struct { // Tool calling fields ToolCall *ToolCall `json:"tool_call,omitempty"` ToolResult *ToolResult `json:"tool_result,omitempty"` + // Reasoning contains thinking content for AI messages + Reasoning *reasoning.ContentReasoning `json:"reasoning,omitempty"` + // CacheControl for prompt caching (used by Legacy Anthropic API) + CacheControl *CacheControl `json:"cache_control,omitempty"` +} + +// CacheControl represents cache configuration for prompt caching +type CacheControl struct { + Type string `json:"type"` + TTL string `json:"ttl,omitempty"` } // ToolCall represents a function call request from the model diff --git a/llms/bedrock/internal/bedrockclient/bedrockclient_converse.go b/llms/bedrock/internal/bedrockclient/bedrockclient_converse.go index c1fbc75e..ace91e42 100644 --- a/llms/bedrock/internal/bedrockclient/bedrockclient_converse.go +++ b/llms/bedrock/internal/bedrockclient/bedrockclient_converse.go @@ -60,6 +60,7 @@ type ConverseInput struct { Tools []llms.Tool StreamingFunc streaming.Callback ReasoningConfig *llms.ReasoningConfig + EnableCaching bool } type converseThinkingPayload struct { @@ -94,6 +95,11 @@ func (c *ConverseClient) buildConverseInput(input *ConverseInput) (*bedrockrunti inferenceConfig.StopSequences = input.StopSequences } + // Add cachePoint to messages if caching is enabled + if input.EnableCaching && len(converseMessages) > 0 { + c.addCachePointToMessages(converseMessages) + } + converseInput := &bedrockruntime.ConverseInput{ ModelId: aws.String(input.ModelID), Messages: converseMessages, @@ -102,6 +108,15 @@ func (c *ConverseClient) buildConverseInput(input *ConverseInput) (*bedrockrunti // Add system prompts if any if len(systemPrompts) > 0 { + // Add cachePoint after system if caching is enabled + if input.EnableCaching { + systemPrompts = append(systemPrompts, &types.SystemContentBlockMemberCachePoint{ + Value: types.CachePointBlock{ + Type: types.CachePointTypeDefault, + Ttl: types.CacheTTLFiveMinutes, + }, + }) + } converseInput.System = systemPrompts } @@ -152,6 +167,20 @@ func (c *ConverseClient) convertMessages(messages []Message) ([]types.Message, [ if err != nil { return nil, nil, err } + // Add cachePoint if message has cache control + if msg.CacheControl != nil { + cacheBlock := types.CachePointBlock{ + Type: types.CachePointTypeDefault, + } + if msg.CacheControl.TTL == "1h" { + cacheBlock.Ttl = types.CacheTTLOneHour + } else { + cacheBlock.Ttl = types.CacheTTLFiveMinutes + } + converseMsg.Content = append(converseMsg.Content, &types.ContentBlockMemberCachePoint{ + Value: cacheBlock, + }) + } converseMessages = append(converseMessages, converseMsg) case llms.ChatMessageTypeTool: converseMsg, err := c.convertToolMessage(msg) @@ -165,6 +194,22 @@ func (c *ConverseClient) convertMessages(messages []Message) ([]types.Message, [ return converseMessages, systemPrompts, nil } +// addCachePointToMessages adds cachePoint to the last message for conversation history caching +func (c *ConverseClient) addCachePointToMessages(messages []types.Message) { + if len(messages) == 0 { + return + } + + // Add cachePoint to the last message's content + lastMsg := &messages[len(messages)-1] + lastMsg.Content = append(lastMsg.Content, &types.ContentBlockMemberCachePoint{ + Value: types.CachePointBlock{ + Type: types.CachePointTypeDefault, + Ttl: types.CacheTTLFiveMinutes, + }, + }) +} + // convertUserOrAssistantMessage converts user or assistant messages func (c *ConverseClient) convertUserOrAssistantMessage(msg Message) (types.Message, error) { var role types.ConversationRole @@ -176,6 +221,31 @@ func (c *ConverseClient) convertUserOrAssistantMessage(msg Message) (types.Messa var contentBlocks []types.ContentBlock + // For AI messages with reasoning, add reasoning blocks first + if msg.Role == llms.ChatMessageTypeAI && msg.Reasoning != nil { + // Add thinking block if present + if msg.Reasoning.Content != "" || len(msg.Reasoning.Signature) > 0 { + reasoningBlock := types.ReasoningContentBlockMemberReasoningText{ + Value: types.ReasoningTextBlock{ + Text: ptrStringOrNil(msg.Reasoning.Content), + Signature: ptrStringOrNil(string(msg.Reasoning.Signature)), + }, + } + contentBlocks = append(contentBlocks, &types.ContentBlockMemberReasoningContent{ + Value: &reasoningBlock, + }) + } + // Add redacted thinking block if present + if len(msg.Reasoning.RedactedContent) > 0 { + redactedBlock := types.ReasoningContentBlockMemberRedactedContent{ + Value: msg.Reasoning.RedactedContent, + } + contentBlocks = append(contentBlocks, &types.ContentBlockMemberReasoningContent{ + Value: &redactedBlock, + }) + } + } + // Handle text content if msg.Content != "" { contentBlocks = append(contentBlocks, &types.ContentBlockMemberText{ @@ -205,9 +275,11 @@ func (c *ConverseClient) convertToolCallInput(args any) (any, error) { return args, nil } + // Convert to Smithy-compatible format by re-encoding through JSON + // This handles types like map[string]any with interface{} values jsonBytes := bytes.NewBuffer(nil) if err := json.NewEncoder(jsonBytes).Encode(args); err != nil { - return nil, err + return nil, fmt.Errorf("failed to encode arguments: %w", err) } jsonDecoder := json.NewDecoder(jsonBytes) @@ -215,7 +287,7 @@ func (c *ConverseClient) convertToolCallInput(args any) (any, error) { var jsonValue any if err := jsonDecoder.Decode(&jsonValue); err != nil { - return nil, err + return nil, fmt.Errorf("failed to decode arguments: %w", err) } return jsonValue, nil @@ -315,6 +387,8 @@ func (c *ConverseClient) handleStreamingResponse(ctx context.Context, input *bed func (c *ConverseClient) processStreamingResponse(ctx context.Context, response *bedrockruntime.ConverseStreamOutput, callback streaming.Callback) (*llms.ContentResponse, error) { var fullContent strings.Builder var reasoningContent strings.Builder + var signature bytes.Buffer + var redactedContent bytes.Buffer var toolCalls []llms.ToolCall currentToolCalls := make(map[string]*streaming.ToolCall) // Track streaming tool calls by ID @@ -352,9 +426,13 @@ func (c *ConverseClient) processStreamingResponse(ctx context.Context, response return nil, err } case *types.ReasoningContentBlockDeltaMemberRedactedContent: - // TODO: not supported yet + if len(block.Value) > 0 { + redactedContent.Write(block.Value) + } case *types.ReasoningContentBlockDeltaMemberSignature: - // TODO: not supported yet + if len(block.Value) > 0 { + signature.WriteString(block.Value) + } } } case *types.ContentBlockDeltaMemberToolUse: @@ -433,11 +511,20 @@ func (c *ConverseClient) processStreamingResponse(ctx context.Context, response return nil, fmt.Errorf("stream error: %w", err) } + var sig []byte + if signature.Len() > 0 { + sig = signature.Bytes() + } + var redacted []byte + if redactedContent.Len() > 0 { + redacted = redactedContent.Bytes() + } + choice := &llms.ContentChoice{ Content: fullContent.String(), ToolCalls: toolCalls, GenerationInfo: make(map[string]any), - Reasoning: c.processReasoning(reasoningContent.String()), + Reasoning: c.processReasoning(reasoningContent.String(), sig, redacted), } result := &llms.ContentResponse{ @@ -447,13 +534,15 @@ func (c *ConverseClient) processStreamingResponse(ctx context.Context, response return result, nil } -func (c *ConverseClient) processReasoning(reasoningContent string) *reasoning.ContentReasoning { - if reasoningContent == "" { +func (c *ConverseClient) processReasoning(reasoningContent string, signature []byte, redactedContent []byte) *reasoning.ContentReasoning { + if reasoningContent == "" && len(signature) == 0 && len(redactedContent) == 0 { return nil } return &reasoning.ContentReasoning{ - Content: reasoningContent, + Content: reasoningContent, + Signature: signature, + RedactedContent: redactedContent, } } @@ -477,7 +566,17 @@ func (c *ConverseClient) convertConverseResponse(response *bedrockruntime.Conver choice.Content += block.Value case *types.ContentBlockMemberToolUse: // Convert tool use to ToolCall - argsJSON, _ := json.Marshal(block.Value.Input) + // Extract input from document.LazyDocument + var inputData any + if block.Value.Input != nil { + if err := block.Value.Input.UnmarshalSmithyDocument(&inputData); err != nil { + return nil, fmt.Errorf("failed to unmarshal tool input document: %w", err) + } + } + argsJSON, err := json.Marshal(inputData) + if err != nil { + return nil, fmt.Errorf("failed to marshal tool input to JSON: %w", err) + } toolCall := llms.ToolCall{ ID: *block.Value.ToolUseId, Type: "function", @@ -488,14 +587,28 @@ func (c *ConverseClient) convertConverseResponse(response *bedrockruntime.Conver } choice.ToolCalls = append(choice.ToolCalls, toolCall) case *types.ContentBlockMemberReasoningContent: - // The block.Value is of type ReasoningContentBlock, not string - // TODO: Extract text from reasoning block when AWS SDK exposes it + // The block.Value is of type ReasoningContentBlock switch content := block.Value.(type) { case *types.ReasoningContentBlockMemberReasoningText: - choice.Reasoning = c.processReasoning(*content.Value.Text) - _ = content.Value.Signature // TODO: not supported yet + reasoningText := "" + if content.Value.Text != nil { + reasoningText = *content.Value.Text + } + var sig []byte + if content.Value.Signature != nil { + sig = []byte(*content.Value.Signature) + } + choice.Reasoning = c.processReasoning(reasoningText, sig, nil) case *types.ReasoningContentBlockMemberRedactedContent: - // TODO: not supported yet + var redacted []byte + if len(content.Value) > 0 { + redacted = content.Value + } + if choice.Reasoning == nil { + choice.Reasoning = c.processReasoning("", nil, redacted) + } else { + choice.Reasoning.RedactedContent = redacted + } } } } @@ -508,12 +621,25 @@ func (c *ConverseClient) convertConverseResponse(response *bedrockruntime.Conver if response.Usage != nil { if response.Usage.InputTokens != nil { choice.GenerationInfo["input_tokens"] = *response.Usage.InputTokens + choice.GenerationInfo["PromptTokens"] = *response.Usage.InputTokens } if response.Usage.OutputTokens != nil { choice.GenerationInfo["output_tokens"] = *response.Usage.OutputTokens + choice.GenerationInfo["CompletionTokens"] = *response.Usage.OutputTokens } if response.Usage.TotalTokens != nil { choice.GenerationInfo["total_tokens"] = *response.Usage.TotalTokens + choice.GenerationInfo["TotalTokens"] = *response.Usage.TotalTokens + } + // Add cache metrics if available + if response.Usage.CacheReadInputTokens != nil { + choice.GenerationInfo["cacheReadInputTokens"] = *response.Usage.CacheReadInputTokens + choice.GenerationInfo["CacheReadInputTokens"] = *response.Usage.CacheReadInputTokens + choice.GenerationInfo["PromptCachedTokens"] = *response.Usage.CacheReadInputTokens + } + if response.Usage.CacheWriteInputTokens != nil { + choice.GenerationInfo["cacheWriteInputTokens"] = *response.Usage.CacheWriteInputTokens + choice.GenerationInfo["CacheCreationInputTokens"] = *response.Usage.CacheWriteInputTokens } } @@ -530,7 +656,11 @@ func (c *ConverseClient) supportsReasoning(modelID string) bool { reasoningModels := []string{ "anthropic.claude-opus-4-", "anthropic.claude-sonnet-4-", + "anthropic.claude-haiku-4-", "anthropic.claude-3-7-", + "openai.gpt-oss-120b", + "openai.gpt-oss-20b", + "moonshot.kimi-k2-thinking", } for _, model := range reasoningModels { @@ -540,3 +670,10 @@ func (c *ConverseClient) supportsReasoning(modelID string) bool { } return false } + +func ptrStringOrNil(s string) *string { + if s == "" { + return nil + } + return &s +} diff --git a/llms/bedrock/internal/bedrockclient/bedrockclient_integration_test.go b/llms/bedrock/internal/bedrockclient/bedrockclient_integration_test.go index 48b2e32a..678699d4 100644 --- a/llms/bedrock/internal/bedrockclient/bedrockclient_integration_test.go +++ b/llms/bedrock/internal/bedrockclient/bedrockclient_integration_test.go @@ -176,8 +176,14 @@ func TestClient_CreateCompletion(t *testing.T) { }, StopReason: AnthropicCompletionReasonEndTurn, Usage: struct { - InputTokens int32 `json:"input_tokens"` - OutputTokens int32 `json:"output_tokens"` + InputTokens int32 `json:"input_tokens"` + OutputTokens int32 `json:"output_tokens"` + CacheCreationInputTokens int32 `json:"cache_creation_input_tokens,omitempty"` + CacheReadInputTokens int32 `json:"cache_read_input_tokens,omitempty"` + CacheCreation struct { + Ephemeral5mInputTokens int32 `json:"ephemeral_5m_input_tokens,omitempty"` + Ephemeral1hInputTokens int32 `json:"ephemeral_1h_input_tokens,omitempty"` + } `json:"cache_creation,omitempty"` }{ InputTokens: 10, OutputTokens: 5, @@ -470,6 +476,7 @@ func TestClient_CreateCompletion_Streaming(t *testing.T) { StopReason string `json:"stop_reason"` StopSequence any `json:"stop_sequence"` Thinking string `json:"thinking,omitempty"` + Signature string `json:"signature,omitempty"` }{ Type: "text_delta", Text: "Once upon a time, ", @@ -485,6 +492,7 @@ func TestClient_CreateCompletion_Streaming(t *testing.T) { StopReason string `json:"stop_reason"` StopSequence any `json:"stop_sequence"` Thinking string `json:"thinking,omitempty"` + Signature string `json:"signature,omitempty"` }{ Type: "text_delta", Text: "there was a brave knight.", @@ -499,6 +507,7 @@ func TestClient_CreateCompletion_Streaming(t *testing.T) { StopReason string `json:"stop_reason"` StopSequence any `json:"stop_sequence"` Thinking string `json:"thinking,omitempty"` + Signature string `json:"signature,omitempty"` }{ StopReason: AnthropicCompletionReasonEndTurn, }, @@ -792,6 +801,7 @@ func TestClient_CreateCompletion_StreamingCancellation(t *testing.T) { StopReason string `json:"stop_reason"` StopSequence any `json:"stop_sequence"` Thinking string `json:"thinking,omitempty"` + Signature string `json:"signature,omitempty"` }{ Type: "text_delta", Text: fmt.Sprintf("Chunk %d ", i), diff --git a/llms/bedrock/internal/bedrockclient/bedrockclient_test.go b/llms/bedrock/internal/bedrockclient/bedrockclient_test.go index 5c42d675..ea9c01a5 100644 --- a/llms/bedrock/internal/bedrockclient/bedrockclient_test.go +++ b/llms/bedrock/internal/bedrockclient/bedrockclient_test.go @@ -675,8 +675,14 @@ func TestAnthropicResponseParsing(t *testing.T) { StopReason: AnthropicCompletionReasonEndTurn, StopSequence: "", Usage: struct { - InputTokens int32 `json:"input_tokens"` - OutputTokens int32 `json:"output_tokens"` + InputTokens int32 `json:"input_tokens"` + OutputTokens int32 `json:"output_tokens"` + CacheCreationInputTokens int32 `json:"cache_creation_input_tokens,omitempty"` + CacheReadInputTokens int32 `json:"cache_read_input_tokens,omitempty"` + CacheCreation struct { + Ephemeral5mInputTokens int32 `json:"ephemeral_5m_input_tokens,omitempty"` + Ephemeral1hInputTokens int32 `json:"ephemeral_1h_input_tokens,omitempty"` + } `json:"cache_creation,omitempty"` }{ InputTokens: 10, OutputTokens: 15, @@ -777,6 +783,7 @@ func TestAnthropicStreamingResponseChunk(t *testing.T) { StopReason string `json:"stop_reason"` StopSequence any `json:"stop_sequence"` Thinking string `json:"thinking,omitempty"` + Signature string `json:"signature,omitempty"` }{ Type: "text_delta", Text: "Hello, how can I help you today?", @@ -794,6 +801,7 @@ func TestAnthropicStreamingResponseChunk(t *testing.T) { StopReason string `json:"stop_reason"` StopSequence any `json:"stop_sequence"` Thinking string `json:"thinking,omitempty"` + Signature string `json:"signature,omitempty"` }{ StopReason: AnthropicCompletionReasonEndTurn, }, diff --git a/llms/bedrock/internal/bedrockclient/provider_anthropic.go b/llms/bedrock/internal/bedrockclient/provider_anthropic.go index ee96dcab..ae4dae3d 100644 --- a/llms/bedrock/internal/bedrockclient/provider_anthropic.go +++ b/llms/bedrock/internal/bedrockclient/provider_anthropic.go @@ -37,7 +37,7 @@ type anthropicBinGenerationInputSource struct { // anthropicTextGenerationInputContent is a single message in the input. type anthropicTextGenerationInputContent struct { // The type of the content. Required. - // One of: "text", "image", "tool_use", "tool_result" + // One of: "text", "image", "tool_use", "tool_result", "thinking", "redacted_thinking" Type string `json:"type"` // The source of the content. Required if type is "image" Source *anthropicBinGenerationInputSource `json:"source,omitempty"` @@ -50,6 +50,17 @@ type anthropicTextGenerationInputContent struct { // Tool result fields ToolUseID string `json:"tool_use_id,omitempty"` Content string `json:"content,omitempty"` + // Thinking fields + Thinking string `json:"thinking,omitempty"` + Signature string `json:"signature,omitempty"` + Data string `json:"data,omitempty"` + // Cache control for prompt caching (Bedrock supports Anthropic cache_control format) + CacheControl *anthropicCacheControl `json:"cache_control,omitempty"` +} + +type anthropicCacheControl struct { + Type string `json:"type"` + TTL string `json:"ttl,omitempty"` } type anthropicTextGenerationInputMessage struct { @@ -68,7 +79,8 @@ type anthropicTextGenerationInput struct { // The maximum number of tokens to generate per result. Required MaxTokens int `json:"max_tokens"` // The system prompt to use. Optional - System string `json:"system,omitempty"` + // Can be string or []anthropicTextGenerationInputContent for caching support + System any `json:"system,omitempty"` // The messages to use. Required Messages []*anthropicTextGenerationInputMessage `json:"messages"` // The amount of randomness injected into the response. Optional, default = 1 @@ -88,9 +100,10 @@ type anthropicTextGenerationInput struct { } type anthropicTool struct { - Name string `json:"name"` - Description string `json:"description,omitempty"` - InputSchema any `json:"input_schema,omitempty"` + Name string `json:"name"` + Description string `json:"description,omitempty"` + InputSchema any `json:"input_schema,omitempty"` + CacheControl *anthropicCacheControl `json:"cache_control,omitempty"` } type anthropicThinkingPayload struct { @@ -114,19 +127,27 @@ type anthropicTextGenerationOutput struct { StopReason string `json:"stop_reason"` // Which custom stop sequence was matched, if any. StopSequence string `json:"stop_sequence"` - Usage struct { - InputTokens int32 `json:"input_tokens"` - OutputTokens int32 `json:"output_tokens"` + Usage struct { + InputTokens int32 `json:"input_tokens"` + OutputTokens int32 `json:"output_tokens"` + CacheCreationInputTokens int32 `json:"cache_creation_input_tokens,omitempty"` + CacheReadInputTokens int32 `json:"cache_read_input_tokens,omitempty"` + CacheCreation struct { + Ephemeral5mInputTokens int32 `json:"ephemeral_5m_input_tokens,omitempty"` + Ephemeral1hInputTokens int32 `json:"ephemeral_1h_input_tokens,omitempty"` + } `json:"cache_creation,omitempty"` } `json:"usage"` } type anthropicContentBlock struct { - Type string `json:"type"` - Text string `json:"text,omitempty"` - ID string `json:"id,omitempty"` - Name string `json:"name,omitempty"` - Input map[string]any `json:"input,omitempty"` - Thinking string `json:"thinking,omitempty"` + Type string `json:"type"` + Text string `json:"text,omitempty"` + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Input map[string]any `json:"input,omitempty"` + Thinking string `json:"thinking,omitempty"` + Signature string `json:"signature,omitempty"` + Data string `json:"data,omitempty"` } // Finish reason for the completion of the generation. @@ -176,10 +197,16 @@ func createAnthropicCompletion(ctx context.Context, } } + // Prepare system prompt - omit if empty + var system any + if systemPrompt != "" { + system = systemPrompt + } + input := anthropicTextGenerationInput{ AnthropicVersion: AnthropicLatestVersion, MaxTokens: getMaxTokens(options.MaxTokens, 2048), - System: systemPrompt, + System: system, Messages: inputContents, Temperature: options.Temperature, TopP: options.TopP, @@ -244,6 +271,8 @@ func createAnthropicCompletion(ctx context.Context, // Group content blocks by type for this choice var textContent string var reasoningContent string + var signature []byte + var redactedContent []byte var toolCalls []llms.ToolCall for _, c := range output.Content { @@ -252,6 +281,13 @@ func createAnthropicCompletion(ctx context.Context, textContent += c.Text case "thinking": reasoningContent += c.Thinking + if len(c.Signature) > 0 { + signature = []byte(c.Signature) + } + case "redacted_thinking": + if len(c.Data) > 0 { + redactedContent = []byte(c.Data) + } case "tool_use": argumentsJSON, err := json.Marshal(c.Input) if err != nil { @@ -271,16 +307,21 @@ func createAnthropicCompletion(ctx context.Context, // Create single choice with all content choice := &llms.ContentChoice{ Content: textContent, - Reasoning: processReasoning(reasoningContent), + Reasoning: processReasoning(reasoningContent, signature, redactedContent), ToolCalls: toolCalls, StopReason: output.StopReason, GenerationInfo: map[string]any{ - "input_tokens": output.Usage.InputTokens, - "output_tokens": output.Usage.OutputTokens, - // Standardized field names for cross-provider compatibility + "input_tokens": output.Usage.InputTokens, + "output_tokens": output.Usage.OutputTokens, "PromptTokens": output.Usage.InputTokens, "CompletionTokens": output.Usage.OutputTokens, "TotalTokens": output.Usage.InputTokens + output.Usage.OutputTokens, + // Cache metrics + "CacheReadInputTokens": output.Usage.CacheReadInputTokens, + "CacheCreationInputTokens": output.Usage.CacheCreationInputTokens, + "CacheCreationEphemeral5mInputTokens": output.Usage.CacheCreation.Ephemeral5mInputTokens, + "CacheCreationEphemeral1hInputTokens": output.Usage.CacheCreation.Ephemeral1hInputTokens, + "PromptCachedTokens": output.Usage.CacheReadInputTokens, }, } Contentchoices = append(Contentchoices, choice) @@ -290,13 +331,15 @@ func createAnthropicCompletion(ctx context.Context, }, nil } -func processReasoning(reasoningContent string) *reasoning.ContentReasoning { - if reasoningContent == "" { +func processReasoning(reasoningContent string, signature []byte, redactedContent []byte) *reasoning.ContentReasoning { + if reasoningContent == "" && len(signature) == 0 && len(redactedContent) == 0 { return nil } return &reasoning.ContentReasoning{ - Content: reasoningContent, + Content: reasoningContent, + Signature: signature, + RedactedContent: redactedContent, } } @@ -310,6 +353,7 @@ type streamingCompletionResponseChunk struct { StopReason string `json:"stop_reason"` StopSequence any `json:"stop_sequence"` Thinking string `json:"thinking,omitempty"` + Signature string `json:"signature,omitempty"` } `json:"delta"` ContentBlock struct { Type string `json:"type"` @@ -356,6 +400,7 @@ func parseStreamingCompletionResponse(ctx context.Context, client *bedrockruntim contentchoices := []*llms.ContentChoice{{GenerationInfo: map[string]any{}}} var currentToolCall *streaming.ToolCall var toolCalls []llms.ToolCall + var signature strings.Builder for e := range stream.Events() { if err = stream.Err(); err != nil { @@ -399,6 +444,13 @@ func parseStreamingCompletionResponse(ctx context.Context, client *bedrockruntim } contentchoices[0].Reasoning = appendReasoning(contentchoices[0].Reasoning, resp.Delta.Thinking) } + if resp.Delta.Signature != "" { + signature.WriteString(resp.Delta.Signature) + } + case "signature_delta": + if resp.Delta.Signature != "" { + signature.WriteString(resp.Delta.Signature) + } case "input_json_delta": if currentToolCall != nil { // Bedrock already sends deltas in PartialJSON, not full accumulated JSON @@ -451,6 +503,11 @@ func parseStreamingCompletionResponse(ctx context.Context, client *bedrockruntim // Add tool calls to the final response contentchoices[0].ToolCalls = toolCalls + // Add signature to reasoning if accumulated + if signature.Len() > 0 && contentchoices[0].Reasoning != nil { + contentchoices[0].Reasoning.Signature = []byte(signature.String()) + } + return &llms.ContentResponse{ Choices: contentchoices, }, nil @@ -458,7 +515,7 @@ func parseStreamingCompletionResponse(ctx context.Context, client *bedrockruntim func appendReasoning(reasoning *reasoning.ContentReasoning, reasoningContent string) *reasoning.ContentReasoning { if reasoning == nil { - return processReasoning(reasoningContent) + return processReasoning(reasoningContent, nil, nil) } reasoning.Content += reasoningContent @@ -507,6 +564,29 @@ func processInputMessagesAnthropic(messages []Message) ([]*anthropicTextGenerati } content := make([]anthropicTextGenerationInputContent, 0, len(chunk)) for _, message := range chunk { + // For AI messages with reasoning, add thinking blocks before text + if message.Role == llms.ChatMessageTypeAI && message.Reasoning != nil { + // Add thinking block if present + if message.Reasoning.Content != "" || len(message.Reasoning.Signature) > 0 { + thinkingBlock := anthropicTextGenerationInputContent{ + Type: "thinking", + Thinking: message.Reasoning.Content, + } + if len(message.Reasoning.Signature) > 0 { + thinkingBlock.Signature = string(message.Reasoning.Signature) + } + content = append(content, thinkingBlock) + } + // Add redacted_thinking block if present + if len(message.Reasoning.RedactedContent) > 0 { + redactedBlock := anthropicTextGenerationInputContent{ + Type: "redacted_thinking", + Data: string(message.Reasoning.RedactedContent), + } + content = append(content, redactedBlock) + } + } + // Add regular content (text, tool_use, tool_result, etc.) content = append(content, getAnthropicInputContent(message)) } inputContents = append(inputContents, &anthropicTextGenerationInputMessage{ @@ -547,6 +627,12 @@ func getAnthropicInputContent(message Message) anthropicTextGenerationInputConte Type: message.Type, Text: message.Content, } + if message.CacheControl != nil { + c.CacheControl = &anthropicCacheControl{ + Type: message.CacheControl.Type, + TTL: message.CacheControl.TTL, + } + } case AnthropicMessageTypeImage: c = anthropicTextGenerationInputContent{ Type: message.Type, @@ -572,6 +658,12 @@ func getAnthropicInputContent(message Message) anthropicTextGenerationInputConte ToolUseID: message.ToolResult.ToolCallID, Content: message.ToolResult.Content, } + if message.CacheControl != nil { + c.CacheControl = &anthropicCacheControl{ + Type: message.CacheControl.Type, + TTL: message.CacheControl.TTL, + } + } } } return c diff --git a/llms/bedrock/models_list.go b/llms/bedrock/models_list.go index 0a1d3a9a..51ecf4ce 100644 --- a/llms/bedrock/models_list.go +++ b/llms/bedrock/models_list.go @@ -65,6 +65,24 @@ const ( // Languages: 200+ languages. ModelAmazonNovaMicroV1 = "us.amazon.nova-micro-v1:0" + // Claude Opus 4.6 is the world's best model for coding, enterprise agents, and professional work. + // It excels at agentic workflows, orchestrating complex tasks across dozens of tools with industry-leading + // reliability. It handles the full lifecycle from architecture to deployment, delivers the deepest reasoning + // for security workflows, and is Anthropic's most capable model for financial workflows and computer use. + // + // Max tokens: 1M (beta) + // Languages: English, French, Modern Standard Arabic, Mandarin Chinese, Hindi, Spanish, Portuguese, Korean, Japanese, German, Russian, Polish, and other languages. + ModelAnthropicClaudeOpus46 = "us.anthropic.claude-opus-4-6-v1" + + // Claude Sonnet 4.6 delivers frontier intelligence at scale—built for coding, agents, and enterprise workflows. + // It excels at complex, multi-step tasks requiring sustained reasoning and adaptive decision-making, handles + // iterative development work with complex codebases, and brings professional-grade analysis with memory to + // maintain context across files. Step-change improvement in creating spreadsheets, slides, and docs. + // + // Max tokens: 1M (beta) + // Languages: English, French, Modern Standard Arabic, Mandarin Chinese, Hindi, Spanish, Portuguese, Korean, Japanese, German, Russian, Polish, and other languages. + ModelAnthropicClaudeSonnet46 = "us.anthropic.claude-sonnet-4-6" + // Claude Opus 4.5 is the next generation of Anthropic's most intelligent model, an industry leader // across coding, agents, computer use, and enterprise workflows. It can confidently deliver multi-day // software development projects in hours, working independently with technical depth. @@ -219,6 +237,17 @@ const ( // Languages: English. ModelMetaLlama38bInstructV1 = "meta.llama3-8b-instruct-v1:0" + // DeepSeek-V3.2 harmonizes high computational efficiency with superior reasoning and agent performance. + // It builds on DeepSeek Sparse Attention for long-context efficiency, a scalable reinforcement learning framework, + // and a large-scale agentic task synthesis pipeline. This model excels at long-context reasoning and agentic tasks, + // efficiently handling extended inputs while maintaining strong accuracy. Its sparse attention design enables it to + // process complex, multi-step workflows without excessive compute costs. Targets long-context reasoning, + // tool-using agents, and efficient deployment in production environments. + // + // Max tokens: 164k + // Languages: English, Chinese. + ModelDeepSeekV32 = "deepseek.v3.2" + // DeepSeek-R1 provides customers a state-of-the-art reasoning model, optimized for general reasoning tasks, // math, science, and code generation. This model is created by DeepSeek and developed through a combination // of cold-start data and reinforcement learning. DeepSeek-R1 is a text-only model supporting English and Chinese. @@ -243,38 +272,54 @@ const ( // Languages: English. ModelOpenAIGptOss20BV1 = "openai.gpt-oss-20b-1:0" - // Qwen3 Next 80B A3B is an 80B-parameter MixtureOfExperts (MOE) language model (3B active) optimized - // for instruction following and ultra-long-context tasks. It delivers flagship-level reasoning, coding, - // and agent performance with only 3B active parameters per token. + // Qwen3 Next 80B A3B turns cutting-edge MoE and hybrid attention into a practical, ultra-long-context assistant + // that scales from everyday chat to million-token workflows. It delivers flagship-level reasoning, coding, + // and agent performance with only 3B active parameters per token. Ideal for long-context summarization, + // code generation/refactoring, enterprise knowledge QA, and stable agentic workflows with tools. // // Max tokens: 256k // Languages: English, Chinese. ModelQwen3Next80BA3B = "qwen.qwen3-next-80b-a3b" - // Qwen3 VL 235B A22B is a 235B-parameter MoE vision-language flagship model (about 22B active) for - // high-end multimodal tasks, combining strong text generation with advanced visual perception, - // 2D/3D spatial grounding, long-context document/video understanding, and multilingual OCR over very long contexts. + // Qwen3 VL 235B A22B is a frontier vision-language model that sees, reads, and reasons across images, documents, + // and long videos at massive scale. Its 235B-parameter MoE architecture (≈22B active) delivers state-of-the-art + // multimodal understanding, OCR, and spatial reasoning over contexts reaching hundreds of thousands of tokens. + // Ideal for document intelligence (OCR + layout), multimodal RAG, visual QA, and UI/scene understanding. // // Max tokens: 256k // Languages: English, Chinese. ModelQwen3VL235BA22B = "qwen.qwen3-vl-235b-a22b" - // Qwen3 32B (dense) is a balanced dense model offering strong reasoning and general-purpose performance - // with simple, predictable deployment across standard infra. It delivers performance that surpasses many - // larger models and proves highly versatile across reasoning, coding, and research use cases. + // Qwen3 32B is a balanced dense model that offers strong reasoning and general-purpose performance with + // straightforward deployment on standard infrastructure. Despite its smaller size compared to frontier-scale + // models, Qwen3-32B delivers performance that surpasses many larger models, and proves highly versatile across + // reasoning, coding, and research use cases. Its balance of capability, cost efficiency, and operational + // simplicity has made it one of the most practical and widely deployable models in the Qwen3 family. // // Max tokens: 16384 // Languages: English, Chinese. ModelQwen332BV1 = "qwen.qwen3-32b-v1:0" - // Qwen3-Coder-30B-A3B-Instruct delivers strong coding and reasoning performance in a compact MoE design. - // It excels at "vibe coding," natural-language-first programming, debugging, SQL generation, and other - // development workflows, while being lightweight enough to run on single high-memory GPUs or small clusters. + // Qwen3-Coder-30B-A3B-Instruct delivers strong coding and reasoning performance in a compact MoE design, making + // it one of the most widely adopted models in the Qwen3-Coder series. It has become a favorite among developers + // and enterprises seeking a practical balance between cost and capability. The model excels at "vibe coding," + // natural-language-first programming, debugging, SQL generation, and other development workflows, while being + // lightweight enough to run on single high-memory GPUs or small clusters. // // Max tokens: 262144 // Languages: English, Chinese. ModelQwen3Coder30BA3BV1 = "qwen.qwen3-coder-30b-a3b-v1:0" + // Qwen3-Coder-Next is an open-weight language model built specifically for coding, with strong performance + // on large-scale software engineering and agentic coding benchmarks. It uses a hybrid Mixture-of-Experts + // architecture to offer high capability at relatively modest active parameter counts, improving efficiency + // for real-world deployments. Optimized for tool use and function calling, making it suitable as the core + // of coding agents that interact with shells, editors, issue trackers, and other developer tools. + // + // Max tokens: 256k + // Languages: English, Chinese. + ModelQwen3CoderNext = "qwen.qwen3-coder-next" + // Mistral Large 3 is Mistral's most advanced open-weight multimodal model, combining a granular // Mixture-of-Experts architecture (673B total parameters with 39B active, plus a 2.5B vision encoder) // and a 256k context window to deliver state-of-the-art reliability, long-context reasoning, and @@ -299,11 +344,43 @@ const ( // Languages: English, French, German, Spanish, Chinese, Japanese, and multiple other languages. ModelMistralLarge2402V1 = "mistral.mistral-large-2402-v1:0" + // Kimi K2.5 brings together strong vision, language, and code capabilities in a single natively multimodal + // architecture. It handles complex tasks that mix images and text—such as generating code from UI mockups + // or analyzing visual documents—with high accuracy. The model's "thinking" mode enables deep, deliberate reasoning, + // while "instant" mode provides fast responses for interactive use. Its built-in support for tool use and agent + // orchestration makes it highly effective for building sophisticated multimodal assistants. + // + // Max tokens: 256k + // Languages: English, Chinese. + ModelMoonshotKimiK25 = "moonshotai.kimi-k2.5" + // Kimi K2 Thinking is Moonshot AI's flagship "thinking agent" model, designed for deep, tool-augmented reasoning. - // Its 1T-parameter MoE architecture (32B active) powers state-of-the-art performance on long-horizon tasks. - // Native INT4 quantization and a 256K context window enable serious research- and agent-style workloads with practical hardware. + // Its 1T-parameter MoE architecture (32B active) powers state-of-the-art performance on long-horizon tasks like + // HLE and BrowseComp. Native INT4 quantization and a 256K context window enable serious research- and agent-style + // workloads with practical hardware. Ideal for long-horizon planning with tools, complex coding and debugging, + // research agents over large corpora, and workflows needing 200-300-step stable tool orchestration. // // Max tokens: 256k // Languages: Multilingual (including Chinese and English). ModelMoonshotKimiK2Thinking = "moonshot.kimi-k2-thinking" + + // GLM-4.7 is a general-purpose language model in the GLM family with a focus on generating clean, modern + // front-end code and web interfaces. It can turn natural-language descriptions into structured HTML, CSS, + // and JavaScript while also supporting standard text and reasoning tasks. The model is positioned for developers + // who want high-quality UI outputs alongside general conversational and coding abilities. It remains compatible + // with typical LLM use cases such as question answering, summarization, and dialogue. + // + // Max tokens: 203k + // Languages: English, Chinese. + ModelGLM47 = "zai.glm-4.7" + + // GLM-4.7-Flash is a lightweight variant of GLM-4.7, using a mixture-of-experts architecture to reduce + // resource requirements while maintaining strong output quality. It is designed for scenarios where low latency + // and cost efficiency are important, such as interactive assistants or high-traffic services. The model retains + // the core text and code generation capabilities of GLM-4.7 in a smaller active-parameter footprint. + // A practical choice when deployment constraints limit the use of larger models. + // + // Max tokens: 203k + // Languages: English, Chinese. + ModelGLM47Flash = "zai.glm-4.7-flash" ) diff --git a/llms/bedrock/testdata/TestAmazonAutomaticCachingConverseAPI.httprr b/llms/bedrock/testdata/TestAmazonAutomaticCachingConverseAPI.httprr new file mode 100644 index 00000000..0e9e0d24 --- /dev/null +++ b/llms/bedrock/testdata/TestAmazonAutomaticCachingConverseAPI.httprr @@ -0,0 +1,44 @@ +httprr trace v1 +5775 654 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 5470 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"What's the weather in Boston?"},{"cachePoint":{"ttl":"5m","type":"default"}}],"role":"user"}],"system":[{"text":"BedrockConverseAutoCacheTest-v1: You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. "},{"cachePoint":{"ttl":"5m","type":"default"}}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"BedrockConverseAutoCacheTest-v1: Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. ","inputSchema":{"json":{"properties":{"location":{"description":"City and state, e.g. San Francisco, CA","type":"string"}},"required":["location"],"type":"object"}},"name":"get_weather"}}]}}HTTP/2.0 200 OK +Content-Length: 489 +Content-Type: application/json +Date: Tue, 03 Mar 2026 21:48:45 GMT +X-Amzn-Requestid: 5ef614ca-5045-4baf-995e-e27fb4cad3a7 + +{"metrics":{"latencyMs":2618},"output":{"message":{"content":[{"toolUse":{"input":{"location":"Boston, MA"},"name":"get_weather","toolUseId":"tooluse_1ncUndhOL9u3hhFVuhOwlP","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheDetails":[{"inputTokens":1365,"ttl":"5m"}],"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":1365,"cacheWriteInputTokens":1365,"inputTokens":3,"outputTokens":55,"serverToolUsage":{},"totalTokens":1423}}6083 629 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 5778 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"What's the weather in Boston?"}],"role":"user"},{"content":[{"toolUse":{"input":{"location":"Boston, MA"},"name":"get_weather","toolUseId":"tooluse_1ncUndhOL9u3hhFVuhOwlP"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"{\"temperature\": 72, \"condition\": \"sunny\"}"}],"toolUseId":"tooluse_1ncUndhOL9u3hhFVuhOwlP"}},{"cachePoint":{"ttl":"5m","type":"default"}}],"role":"user"}],"system":[{"text":"BedrockConverseAutoCacheTest-v1: You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. "},{"cachePoint":{"ttl":"5m","type":"default"}}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"BedrockConverseAutoCacheTest-v1: Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. ","inputSchema":{"json":{"properties":{"location":{"description":"City and state, e.g. San Francisco, CA","type":"string"}},"required":["location"],"type":"object"}},"name":"get_weather"}}]}}HTTP/2.0 200 OK +Content-Length: 464 +Content-Type: application/json +Date: Tue, 03 Mar 2026 21:48:48 GMT +X-Amzn-Requestid: ba5d0941-90f6-4e82-ac10-2c5a953f3227 + +{"metrics":{"latencyMs":2275},"output":{"message":{"content":[{"text":"The weather in Boston, MA is currently sunny with a temperature of 72°F. It's a beautiful day!"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheDetails":[{"inputTokens":77,"ttl":"5m"}],"cacheReadInputTokenCount":1365,"cacheReadInputTokens":1365,"cacheWriteInputTokenCount":77,"cacheWriteInputTokens":77,"inputTokens":6,"outputTokens":27,"serverToolUsage":{},"totalTokens":1475}}6328 656 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 6023 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"What's the weather in Boston?"}],"role":"user"},{"content":[{"toolUse":{"input":{"location":"Boston, MA"},"name":"get_weather","toolUseId":"tooluse_1ncUndhOL9u3hhFVuhOwlP"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"{\"temperature\": 72, \"condition\": \"sunny\"}"}],"toolUseId":"tooluse_1ncUndhOL9u3hhFVuhOwlP"}}],"role":"user"},{"content":[{"text":"The weather in Boston, MA is currently sunny with a temperature of 72°F. It's a beautiful day!"},{"cachePoint":{"ttl":"5m","type":"default"}}],"role":"assistant"},{"content":[{"text":"What about New York?"},{"cachePoint":{"ttl":"5m","type":"default"}}],"role":"user"}],"system":[{"text":"BedrockConverseAutoCacheTest-v1: You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. "},{"cachePoint":{"ttl":"5m","type":"default"}}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"BedrockConverseAutoCacheTest-v1: Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. ","inputSchema":{"json":{"properties":{"location":{"description":"City and state, e.g. San Francisco, CA","type":"string"}},"required":["location"],"type":"object"}},"name":"get_weather"}}]}}HTTP/2.0 200 OK +Content-Length: 491 +Content-Type: application/json +Date: Tue, 03 Mar 2026 21:48:51 GMT +X-Amzn-Requestid: e7fb5f6b-35d0-4e8e-85c3-5bc916ba5fd3 + +{"metrics":{"latencyMs":2392},"output":{"message":{"content":[{"toolUse":{"input":{"location":"New York, NY"},"name":"get_weather","toolUseId":"tooluse_aeSvV8u2CNRzTPCTwjgT4x","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheDetails":[{"inputTokens":38,"ttl":"5m"}],"cacheReadInputTokenCount":1442,"cacheReadInputTokens":1442,"cacheWriteInputTokenCount":38,"cacheWriteInputTokens":38,"inputTokens":3,"outputTokens":56,"serverToolUsage":{},"totalTokens":1539}} \ No newline at end of file diff --git a/llms/bedrock/testdata/TestAmazonAutomaticCachingLegacyAPI.httprr b/llms/bedrock/testdata/TestAmazonAutomaticCachingLegacyAPI.httprr new file mode 100644 index 00000000..3368064b --- /dev/null +++ b/llms/bedrock/testdata/TestAmazonAutomaticCachingLegacyAPI.httprr @@ -0,0 +1,62 @@ +httprr trace v1 +5644 861 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/invoke HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 5328 +Accept: */* +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"anthropic_version":"bedrock-2023-05-31","max_tokens":512,"system":"BedrockAutoCacheTest-v1: You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. ","messages":[{"role":"user","content":[{"type":"text","text":"What's the weather in Boston?"}]}],"tools":[{"name":"get_weather","description":"BedrockAutoCacheTest-v1: Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. ","input_schema":{"properties":{"location":{"description":"City and state, e.g. San Francisco, CA","type":"string"}},"required":["location"],"type":"object"}}]}HTTP/2.0 200 OK +Content-Length: 479 +Content-Type: application/json +Date: Tue, 03 Mar 2026 12:08:21 GMT +X-Amzn-Bedrock-Cache-Read-Input-Token-Count: 0 +X-Amzn-Bedrock-Cache-Write-Input-Token-Count: 0 +X-Amzn-Bedrock-Input-Token-Count: 1364 +X-Amzn-Bedrock-Invocation-Latency: 2316 +X-Amzn-Bedrock-Output-Token-Count: 55 +X-Amzn-Requestid: cac76811-ff21-4b4b-a4ab-b898881b8ac1 + +{"model":"claude-sonnet-4-5-20250929","id":"msg_bdrk_018XN9z43PbbVj1CpSArUwwy","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_bdrk_018mXNtJeAPtSRUF5fA81SCg","name":"get_weather","input":{"location":"Boston, MA"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":1364,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":55}}6006 894 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/invoke HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 5690 +Accept: */* +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"anthropic_version":"bedrock-2023-05-31","max_tokens":512,"system":"BedrockAutoCacheTest-v1: You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. ","messages":[{"role":"user","content":[{"type":"text","text":"What's the weather in Boston?"}]},{"role":"assistant","content":[{"type":"tool_use","id":"toolu_bdrk_018mXNtJeAPtSRUF5fA81SCg","name":"get_weather","input":{"location":"Boston, MA"}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_018mXNtJeAPtSRUF5fA81SCg","content":"{\"temperature\": 72, \"condition\": \"sunny\"}","cache_control":{"type":"ephemeral","ttl":"5m"}}]}],"tools":[{"name":"get_weather","description":"BedrockAutoCacheTest-v1: Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. ","input_schema":{"properties":{"location":{"description":"City and state, e.g. San Francisco, CA","type":"string"}},"required":["location"],"type":"object"}}]}HTTP/2.0 200 OK +Content-Length: 512 +Content-Type: application/json +Date: Tue, 03 Mar 2026 12:08:24 GMT +X-Amzn-Bedrock-Cache-Read-Input-Token-Count: 0 +X-Amzn-Bedrock-Cache-Write-Input-Token-Count: 1438 +X-Amzn-Bedrock-Input-Token-Count: 6 +X-Amzn-Bedrock-Invocation-Latency: 2013 +X-Amzn-Bedrock-Output-Token-Count: 38 +X-Amzn-Requestid: e078dfdc-a32c-43e9-b857-ac78786862a8 + +{"model":"claude-sonnet-4-5-20250929","id":"msg_bdrk_01N4Zp8XkWCrnmFY1rrCVdqx","type":"message","role":"assistant","content":[{"type":"text","text":"The current weather in Boston, MA is:\n- **Temperature**: 72°F\n- **Condition**: Sunny\n\nIt's a beautiful day in Boston!"}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":6,"cache_creation_input_tokens":1438,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":1438,"ephemeral_1h_input_tokens":0},"output_tokens":38}}6261 868 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/invoke HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 5945 +Accept: */* +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"anthropic_version":"bedrock-2023-05-31","max_tokens":512,"system":"BedrockAutoCacheTest-v1: You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. You are a helpful assistant with access to weather capabilities. ","messages":[{"role":"user","content":[{"type":"text","text":"What's the weather in Boston?"}]},{"role":"assistant","content":[{"type":"tool_use","id":"toolu_bdrk_018mXNtJeAPtSRUF5fA81SCg","name":"get_weather","input":{"location":"Boston, MA"}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_018mXNtJeAPtSRUF5fA81SCg","content":"{\"temperature\": 72, \"condition\": \"sunny\"}"}]},{"role":"assistant","content":[{"type":"text","text":"The current weather in Boston, MA is:\n- **Temperature**: 72°F\n- **Condition**: Sunny\n\nIt's a beautiful day in Boston!","cache_control":{"type":"ephemeral","ttl":"5m"}}]},{"role":"user","content":[{"type":"text","text":"What about New York?"}]}],"tools":[{"name":"get_weather","description":"BedrockAutoCacheTest-v1: Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. ","input_schema":{"properties":{"location":{"description":"City and state, e.g. San Francisco, CA","type":"string"}},"required":["location"],"type":"object"}}]}HTTP/2.0 200 OK +Content-Length: 484 +Content-Type: application/json +Date: Tue, 03 Mar 2026 12:08:28 GMT +X-Amzn-Bedrock-Cache-Read-Input-Token-Count: 1438 +X-Amzn-Bedrock-Cache-Write-Input-Token-Count: 41 +X-Amzn-Bedrock-Input-Token-Count: 11 +X-Amzn-Bedrock-Invocation-Latency: 2445 +X-Amzn-Bedrock-Output-Token-Count: 56 +X-Amzn-Requestid: 4e835349-c4fe-45b3-9146-ceb02826a891 + +{"model":"claude-sonnet-4-5-20250929","id":"msg_bdrk_01FpNQeFvCSh7SoJtHwPDP6d","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_bdrk_01G58eVVMGER3xvhAMk8ZaEu","name":"get_weather","input":{"location":"New York, NY"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":11,"cache_creation_input_tokens":41,"cache_read_input_tokens":1438,"cache_creation":{"ephemeral_5m_input_tokens":41,"ephemeral_1h_input_tokens":0},"output_tokens":56}} \ No newline at end of file diff --git a/llms/bedrock/testdata/TestAmazonMultiTurnCachingWithToolsConverseAPI.httprr b/llms/bedrock/testdata/TestAmazonMultiTurnCachingWithToolsConverseAPI.httprr new file mode 100644 index 00000000..86685c46 --- /dev/null +++ b/llms/bedrock/testdata/TestAmazonMultiTurnCachingWithToolsConverseAPI.httprr @@ -0,0 +1,58 @@ +httprr trace v1 +10113 602 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 9808 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"What's the weather in Boston?"}],"role":"user"}],"system":[{"text":"BedrockConverseCache-v1: You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. "}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"BedrockConverseCache-v1: Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. ","inputSchema":{"json":{"properties":{"location":{"description":"City and state, e.g. San Francisco, CA","type":"string"}},"required":["location"],"type":"object"}},"name":"get_weather"}},{"toolSpec":{"description":"BedrockConverseCache-v1: Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. ","inputSchema":{"json":{"properties":{"date":{"description":"Departure date","type":"string"},"destination":{"description":"Destination city","type":"string"}},"required":["destination","date"],"type":"object"}},"name":"book_flight"}}]}}HTTP/2.0 200 OK +Content-Length: 437 +Content-Type: application/json +Date: Tue, 03 Mar 2026 21:48:25 GMT +X-Amzn-Requestid: d9fc318c-4f76-41ad-bf53-bf56c7c38d58 + +{"metrics":{"latencyMs":2319},"output":{"message":{"content":[{"toolUse":{"input":{"location":"Boston, MA"},"name":"get_weather","toolUseId":"tooluse_hLq2QJgO5f0H7WyOdLMyOx","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":2094,"outputTokens":55,"serverToolUsage":{},"totalTokens":2149}}10422 577 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 10116 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"What's the weather in Boston?"}],"role":"user"},{"content":[{"toolUse":{"input":{"location":"Boston, MA"},"name":"get_weather","toolUseId":"tooluse_hLq2QJgO5f0H7WyOdLMyOx"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"{\"temperature\": 72, \"condition\": \"sunny\"}"}],"toolUseId":"tooluse_hLq2QJgO5f0H7WyOdLMyOx"}}],"role":"user"}],"system":[{"text":"BedrockConverseCache-v1: You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. "}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"BedrockConverseCache-v1: Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. ","inputSchema":{"json":{"properties":{"location":{"description":"City and state, e.g. San Francisco, CA","type":"string"}},"required":["location"],"type":"object"}},"name":"get_weather"}},{"toolSpec":{"description":"BedrockConverseCache-v1: Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. ","inputSchema":{"json":{"properties":{"date":{"description":"Departure date","type":"string"},"destination":{"description":"Destination city","type":"string"}},"required":["destination","date"],"type":"object"}},"name":"book_flight"}}]}}HTTP/2.0 200 OK +Content-Length: 412 +Content-Type: application/json +Date: Tue, 03 Mar 2026 21:48:29 GMT +X-Amzn-Requestid: 67b89095-6b61-4a77-879c-3169194c331e + +{"metrics":{"latencyMs":2746},"output":{"message":{"content":[{"text":"The weather in Boston, MA is currently sunny with a temperature of 72°F. It's a beautiful day!"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":2174,"outputTokens":27,"serverToolUsage":{},"totalTokens":2201}}10777 908 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 10471 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"What's the weather in Boston?"}],"role":"user"},{"content":[{"toolUse":{"input":{"location":"Boston, MA"},"name":"get_weather","toolUseId":"tooluse_hLq2QJgO5f0H7WyOdLMyOx"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"{\"temperature\": 72, \"condition\": \"sunny\"}"}],"toolUseId":"tooluse_hLq2QJgO5f0H7WyOdLMyOx"}}],"role":"user"},{"content":[{"text":"The weather in Boston, MA is currently sunny with a temperature of 72°F. It's a beautiful day!"},{"cachePoint":{"ttl":"5m","type":"default"}}],"role":"assistant"},{"content":[{"text":"Now book a flight to Boston for tomorrow"},{"cachePoint":{"ttl":"5m","type":"default"}}],"role":"user"}],"system":[{"text":"BedrockConverseCache-v1: You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. "},{"cachePoint":{"ttl":"5m","type":"default"}}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"BedrockConverseCache-v1: Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. ","inputSchema":{"json":{"properties":{"location":{"description":"City and state, e.g. San Francisco, CA","type":"string"}},"required":["location"],"type":"object"}},"name":"get_weather"}},{"toolSpec":{"description":"BedrockConverseCache-v1: Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. ","inputSchema":{"json":{"properties":{"date":{"description":"Departure date","type":"string"},"destination":{"description":"Destination city","type":"string"}},"required":["destination","date"],"type":"object"}},"name":"book_flight"}}]}}HTTP/2.0 200 OK +Content-Length: 743 +Content-Type: application/json +Date: Tue, 03 Mar 2026 21:48:33 GMT +X-Amzn-Requestid: cbcb4f5a-6d35-4121-9061-5c1a4bc8dad5 + +{"metrics":{"latencyMs":3199},"output":{"message":{"content":[{"text":"I can help you book a flight to Boston for tomorrow! However, I need a bit more information:\n\n1. **Where are you departing from?** (Which city will you be flying from?)\n2. **What is tomorrow's date?** (Please provide the specific date in a format like \"2024-01-15\" or \"January 15, 2024\")\n\nOnce you provide these details, I'll be able to book your flight to Boston."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheDetails":[{"inputTokens":2209,"ttl":"5m"}],"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":2209,"cacheWriteInputTokens":2209,"inputTokens":3,"outputTokens":102,"serverToolUsage":{},"totalTokens":2314}}11317 675 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 11011 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"What's the weather in Boston?"}],"role":"user"},{"content":[{"toolUse":{"input":{"location":"Boston, MA"},"name":"get_weather","toolUseId":"tooluse_hLq2QJgO5f0H7WyOdLMyOx"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"{\"temperature\": 72, \"condition\": \"sunny\"}"}],"toolUseId":"tooluse_hLq2QJgO5f0H7WyOdLMyOx"}}],"role":"user"},{"content":[{"text":"The weather in Boston, MA is currently sunny with a temperature of 72°F. It's a beautiful day!"},{"cachePoint":{"ttl":"5m","type":"default"}}],"role":"assistant"},{"content":[{"text":"Now book a flight to Boston for tomorrow"}],"role":"user"},{"content":[{"text":"I can help you book a flight to Boston for tomorrow! However, I need a bit more information:\n\n1. **Where are you departing from?** (Which city will you be flying from?)\n2. **What is tomorrow's date?** (Please provide the specific date in a format like \"2024-01-15\" or \"January 15, 2024\")\n\nOnce you provide these details, I'll be able to book your flight to Boston."},{"cachePoint":{"ttl":"5m","type":"default"}}],"role":"assistant"},{"content":[{"text":"I'm flying from New York on March 4th"},{"cachePoint":{"ttl":"5m","type":"default"}}],"role":"user"}],"system":[{"text":"BedrockConverseCache-v1: You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. "},{"cachePoint":{"ttl":"5m","type":"default"}}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"BedrockConverseCache-v1: Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. ","inputSchema":{"json":{"properties":{"location":{"description":"City and state, e.g. San Francisco, CA","type":"string"}},"required":["location"],"type":"object"}},"name":"get_weather"}},{"toolSpec":{"description":"BedrockConverseCache-v1: Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. ","inputSchema":{"json":{"properties":{"date":{"description":"Departure date","type":"string"},"destination":{"description":"Destination city","type":"string"}},"required":["destination","date"],"type":"object"}},"name":"book_flight"}}]}}HTTP/2.0 200 OK +Content-Length: 510 +Content-Type: application/json +Date: Tue, 03 Mar 2026 21:48:37 GMT +X-Amzn-Requestid: 0ba50972-8c2f-433a-8e35-e53445779aa2 + +{"metrics":{"latencyMs":2462},"output":{"message":{"content":[{"toolUse":{"input":{"destination":"Boston","date":"March 4th"},"name":"book_flight","toolUseId":"tooluse_IAcLRbQIVFWWhNj83mN6vM","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheDetails":[{"inputTokens":116,"ttl":"5m"}],"cacheReadInputTokenCount":2209,"cacheReadInputTokens":2209,"cacheWriteInputTokenCount":116,"cacheWriteInputTokens":116,"inputTokens":3,"outputTokens":73,"serverToolUsage":{},"totalTokens":2401}} \ No newline at end of file diff --git a/llms/bedrock/testdata/TestAmazonMultiTurnCachingWithToolsLegacyAPI.httprr b/llms/bedrock/testdata/TestAmazonMultiTurnCachingWithToolsLegacyAPI.httprr new file mode 100644 index 00000000..580b5940 --- /dev/null +++ b/llms/bedrock/testdata/TestAmazonMultiTurnCachingWithToolsLegacyAPI.httprr @@ -0,0 +1,82 @@ +httprr trace v1 +10055 861 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/invoke HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 9739 +Accept: */* +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"anthropic_version":"bedrock-2023-05-31","max_tokens":512,"system":"BedrockCacheTest-v1: You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. ","messages":[{"role":"user","content":[{"type":"text","text":"What's the weather in Boston?"}]}],"tools":[{"name":"get_weather","description":"BedrockCacheTest-v1: Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. ","input_schema":{"properties":{"location":{"description":"City and state, e.g. San Francisco, CA","type":"string"}},"required":["location"],"type":"object"}},{"name":"book_flight","description":"BedrockCacheTest-v1: Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. ","input_schema":{"properties":{"date":{"description":"Departure date","type":"string"},"destination":{"description":"Destination city","type":"string"}},"required":["destination","date"],"type":"object"}}]}HTTP/2.0 200 OK +Content-Length: 479 +Content-Type: application/json +Date: Tue, 03 Mar 2026 10:53:28 GMT +X-Amzn-Bedrock-Cache-Read-Input-Token-Count: 0 +X-Amzn-Bedrock-Cache-Write-Input-Token-Count: 0 +X-Amzn-Bedrock-Input-Token-Count: 2094 +X-Amzn-Bedrock-Invocation-Latency: 2115 +X-Amzn-Bedrock-Output-Token-Count: 55 +X-Amzn-Requestid: 388e09c9-86d6-4067-baa6-c16f06bc5ff6 + +{"model":"claude-sonnet-4-5-20250929","id":"msg_bdrk_013Z93U34yWxKWQeVwArGst6","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_bdrk_015MyHjGcqrBnR6psxATkrZb","name":"get_weather","input":{"location":"Boston, MA"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":2094,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":55}}10370 860 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/invoke HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 10053 +Accept: */* +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"anthropic_version":"bedrock-2023-05-31","max_tokens":512,"system":"BedrockCacheTest-v1: You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. ","messages":[{"role":"user","content":[{"type":"text","text":"What's the weather in Boston?"}]},{"role":"assistant","content":[{"type":"tool_use","id":"toolu_bdrk_015MyHjGcqrBnR6psxATkrZb","name":"get_weather","input":{"location":"Boston, MA"}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_015MyHjGcqrBnR6psxATkrZb","content":"{\"temperature\": 72, \"condition\": \"sunny\"}"}]}],"tools":[{"name":"get_weather","description":"BedrockCacheTest-v1: Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. ","input_schema":{"properties":{"location":{"description":"City and state, e.g. San Francisco, CA","type":"string"}},"required":["location"],"type":"object"}},{"name":"book_flight","description":"BedrockCacheTest-v1: Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. ","input_schema":{"properties":{"date":{"description":"Departure date","type":"string"},"destination":{"description":"Destination city","type":"string"}},"required":["destination","date"],"type":"object"}}]}HTTP/2.0 200 OK +Content-Length: 478 +Content-Type: application/json +Date: Tue, 03 Mar 2026 10:53:31 GMT +X-Amzn-Bedrock-Cache-Read-Input-Token-Count: 0 +X-Amzn-Bedrock-Cache-Write-Input-Token-Count: 0 +X-Amzn-Bedrock-Input-Token-Count: 2174 +X-Amzn-Bedrock-Invocation-Latency: 1951 +X-Amzn-Bedrock-Output-Token-Count: 25 +X-Amzn-Requestid: dac236d6-593c-4196-871b-e02d0745a796 + +{"model":"claude-sonnet-4-5-20250929","id":"msg_bdrk_01M8DgnwHAG4oGhYnpP2heEr","type":"message","role":"assistant","content":[{"type":"text","text":"The weather in Boston is currently sunny with a temperature of 72°F. It's a beautiful day!"}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":2174,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":25}}10662 1140 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/invoke HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 10345 +Accept: */* +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"anthropic_version":"bedrock-2023-05-31","max_tokens":512,"system":"BedrockCacheTest-v1: You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. ","messages":[{"role":"user","content":[{"type":"text","text":"What's the weather in Boston?"}]},{"role":"assistant","content":[{"type":"tool_use","id":"toolu_bdrk_015MyHjGcqrBnR6psxATkrZb","name":"get_weather","input":{"location":"Boston, MA"}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_015MyHjGcqrBnR6psxATkrZb","content":"{\"temperature\": 72, \"condition\": \"sunny\"}"}]},{"role":"assistant","content":[{"type":"text","text":"The weather in Boston is currently sunny with a temperature of 72°F. It's a beautiful day!","cache_control":{"type":"ephemeral","ttl":"5m"}}]},{"role":"user","content":[{"type":"text","text":"Now book a flight to Boston for tomorrow"}]}],"tools":[{"name":"get_weather","description":"BedrockCacheTest-v1: Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. ","input_schema":{"properties":{"location":{"description":"City and state, e.g. San Francisco, CA","type":"string"}},"required":["location"],"type":"object"}},{"name":"book_flight","description":"BedrockCacheTest-v1: Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. ","input_schema":{"properties":{"date":{"description":"Departure date","type":"string"},"destination":{"description":"Destination city","type":"string"}},"required":["destination","date"],"type":"object"}}]}HTTP/2.0 200 OK +Content-Length: 756 +Content-Type: application/json +Date: Tue, 03 Mar 2026 10:53:35 GMT +X-Amzn-Bedrock-Cache-Read-Input-Token-Count: 0 +X-Amzn-Bedrock-Cache-Write-Input-Token-Count: 2196 +X-Amzn-Bedrock-Input-Token-Count: 14 +X-Amzn-Bedrock-Invocation-Latency: 2659 +X-Amzn-Bedrock-Output-Token-Count: 101 +X-Amzn-Requestid: 2c4b3131-e5d6-47df-8b1c-560c06e1cbed + +{"model":"claude-sonnet-4-5-20250929","id":"msg_bdrk_01QxskBAVjdmbAbTbYipD8gK","type":"message","role":"assistant","content":[{"type":"text","text":"I can help you book a flight to Boston for tomorrow! However, I need a bit more information:\n\n1. **Where are you departing from?** (Which city will you be flying from?)\n2. **What is tomorrow's date?** (Please provide the date in a format like \"2024-01-15\" or \"January 15, 2024\")\n\nOnce you provide these details, I'll be able to book your flight to Boston."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":14,"cache_creation_input_tokens":2196,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":2196,"ephemeral_1h_input_tokens":0},"output_tokens":101}}11224 887 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/invoke HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 10907 +Accept: */* +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"anthropic_version":"bedrock-2023-05-31","max_tokens":512,"system":"BedrockCacheTest-v1: You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. You are a helpful assistant with access to weather and flight booking capabilities. ","messages":[{"role":"user","content":[{"type":"text","text":"What's the weather in Boston?"}]},{"role":"assistant","content":[{"type":"tool_use","id":"toolu_bdrk_015MyHjGcqrBnR6psxATkrZb","name":"get_weather","input":{"location":"Boston, MA"}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_015MyHjGcqrBnR6psxATkrZb","content":"{\"temperature\": 72, \"condition\": \"sunny\"}"}]},{"role":"assistant","content":[{"type":"text","text":"The weather in Boston is currently sunny with a temperature of 72°F. It's a beautiful day!","cache_control":{"type":"ephemeral","ttl":"5m"}}]},{"role":"user","content":[{"type":"text","text":"Now book a flight to Boston for tomorrow"}]},{"role":"assistant","content":[{"type":"text","text":"I can help you book a flight to Boston for tomorrow! However, I need a bit more information:\n\n1. **Where are you departing from?** (Which city will you be flying from?)\n2. **What is tomorrow's date?** (Please provide the date in a format like \"2024-01-15\" or \"January 15, 2024\")\n\nOnce you provide these details, I'll be able to book your flight to Boston.","cache_control":{"type":"ephemeral","ttl":"5m"}}]},{"role":"user","content":[{"type":"text","text":"I'm flying from New York on March 4th"}]}],"tools":[{"name":"get_weather","description":"BedrockCacheTest-v1: Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. Get current weather conditions including temperature, humidity, wind speed, and precipitation for a specified geographic location. ","input_schema":{"properties":{"location":{"description":"City and state, e.g. San Francisco, CA","type":"string"}},"required":["location"],"type":"object"}},{"name":"book_flight","description":"BedrockCacheTest-v1: Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. Book airline tickets for domestic and international flights with flexible options for departure, arrival, and passenger details. ","input_schema":{"properties":{"date":{"description":"Departure date","type":"string"},"destination":{"description":"Destination city","type":"string"}},"required":["destination","date"],"type":"object"}}]}HTTP/2.0 200 OK +Content-Length: 502 +Content-Type: application/json +Date: Tue, 03 Mar 2026 10:53:38 GMT +X-Amzn-Bedrock-Cache-Read-Input-Token-Count: 2196 +X-Amzn-Bedrock-Cache-Write-Input-Token-Count: 112 +X-Amzn-Bedrock-Input-Token-Count: 17 +X-Amzn-Bedrock-Invocation-Latency: 2206 +X-Amzn-Bedrock-Output-Token-Count: 73 +X-Amzn-Requestid: bda25e46-e221-4954-9598-8284ab448118 + +{"model":"claude-sonnet-4-5-20250929","id":"msg_bdrk_01B5RXNL3fFzZ3332PaVGv4N","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_bdrk_0171AVgL1Nu48z6YsefT1HCa","name":"book_flight","input":{"destination":"Boston","date":"March 4th"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":17,"cache_creation_input_tokens":112,"cache_read_input_tokens":2196,"cache_creation":{"ephemeral_5m_input_tokens":112,"ephemeral_1h_input_tokens":0},"output_tokens":73}} \ No newline at end of file diff --git a/llms/bedrock/testdata/TestAnthropicNovaImage.httprr b/llms/bedrock/testdata/TestAmazonNovaImage.httprr similarity index 100% rename from llms/bedrock/testdata/TestAnthropicNovaImage.httprr rename to llms/bedrock/testdata/TestAmazonNovaImage.httprr diff --git a/llms/bedrock/testdata/TestAmazonOutputConverseAPI.httprr b/llms/bedrock/testdata/TestAmazonOutputConverseAPI.httprr index ac1f559a..7f13cd26 100644 --- a/llms/bedrock/testdata/TestAmazonOutputConverseAPI.httprr +++ b/llms/bedrock/testdata/TestAmazonOutputConverseAPI.httprr @@ -1,5 +1,5 @@ httprr trace v1 -451 444 +451 451 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/ai21.jamba-1-5-large-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -8,12 +8,12 @@ Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK -Content-Length: 279 +Content-Length: 286 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:17:22 GMT -X-Amzn-Requestid: 7438eab0-66e9-48f2-972c-4f4219444a01 +Date: Tue, 03 Mar 2026 15:43:20 GMT +X-Amzn-Requestid: 04655bfd-c846-406d-99b9-80edc7da35fa -{"metrics":{"latencyMs":458},"output":{"message":{"content":[{"text":" Artificial intelligence mimics human intelligence using data and algorithms."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":25,"outputTokens":12,"serverToolUsage":{},"totalTokens":37}}450 442 +{"metrics":{"latencyMs":512},"output":{"message":{"content":[{"text":" AI: Machines simulating human intelligence for problem-solving and decision-making."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":25,"outputTokens":17,"serverToolUsage":{},"totalTokens":42}}450 432 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/ai21.jamba-1-5-mini-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -22,12 +22,12 @@ Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK -Content-Length: 277 +Content-Length: 267 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:17:24 GMT -X-Amzn-Requestid: 7770c26e-0d01-44da-bc12-f7dd212a9c57 +Date: Tue, 03 Mar 2026 15:43:26 GMT +X-Amzn-Requestid: cba8a010-27b9-4abb-b742-869b7afc9def -{"metrics":{"latencyMs":580},"output":{"message":{"content":[{"text":" Intelligent systems mimicking human cognition through algorithms and data."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":25,"outputTokens":12,"serverToolUsage":{},"totalTokens":37}}452 428 +{"metrics":{"latencyMs":323},"output":{"message":{"content":[{"text":" Intelligent systems that learn and make decisions based on data."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":25,"outputTokens":12,"serverToolUsage":{},"totalTokens":37}}452 428 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.amazon.nova-2-lite-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -38,10 +38,10 @@ Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK Content-Length: 263 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:17:26 GMT -X-Amzn-Requestid: 03e7df3e-4308-4837-a629-4741cc48f0d2 +Date: Tue, 03 Mar 2026 15:43:33 GMT +X-Amzn-Requestid: 16890f48-08aa-41e2-8552-f2c67918f4d8 -{"metrics":{"latencyMs":432},"output":{"message":{"content":[{"text":"AI mimics human intelligence through learning and adaptation."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":61,"outputTokens":12,"serverToolUsage":{},"totalTokens":73}}453 427 +{"metrics":{"latencyMs":493},"output":{"message":{"content":[{"text":"AI mimics human intelligence through learning and adaptation."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":61,"outputTokens":12,"serverToolUsage":{},"totalTokens":73}}453 424 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.amazon.nova-premier-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -50,12 +50,12 @@ Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK -Content-Length: 262 +Content-Length: 259 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:17:27 GMT -X-Amzn-Requestid: d616dfaf-471d-44a5-b0b7-3fdb52948d67 +Date: Tue, 03 Mar 2026 15:43:39 GMT +X-Amzn-Requestid: 1592bd01-57b7-4d34-9a18-fb55789064a2 -{"metrics":{"latencyMs":556},"output":{"message":{"content":[{"text":"AI mimics human intelligence using computers and algorithms."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":50,"outputTokens":10,"serverToolUsage":{},"totalTokens":60}}449 428 +{"metrics":{"latencyMs":523},"output":{"message":{"content":[{"text":"AI mimics human intelligence using machines and software."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":50,"outputTokens":10,"serverToolUsage":{},"totalTokens":60}}449 434 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.amazon.nova-pro-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -64,12 +64,12 @@ Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK -Content-Length: 263 +Content-Length: 269 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:17:29 GMT -X-Amzn-Requestid: ee4cd39b-c3b4-41bd-81c1-8e47a5a1e26a +Date: Tue, 03 Mar 2026 15:43:46 GMT +X-Amzn-Requestid: 1a9812f8-ed5c-4626-b548-6bf8e26508de -{"metrics":{"latencyMs":900},"output":{"message":{"content":[{"text":"AI: intelligent machines learning from data, aiding humanity."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":16,"outputTokens":12,"serverToolUsage":{},"totalTokens":28}}450 379 +{"metrics":{"latencyMs":417},"output":{"message":{"content":[{"text":"Machine intelligence mimicking human cognition and decision-making."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":16,"outputTokens":11,"serverToolUsage":{},"totalTokens":27}}450 486 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.amazon.nova-lite-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -78,12 +78,12 @@ Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK -Content-Length: 214 +Content-Length: 321 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:17:31 GMT -X-Amzn-Requestid: 09d1e774-adff-4a6d-af33-dacba8cd2cb5 +Date: Tue, 03 Mar 2026 15:43:53 GMT +X-Amzn-Requestid: 4f1d251a-d3a6-48ba-8971-deaf3babdd43 -{"metrics":{"latencyMs":325},"output":{"message":{"content":[{"text":"Not possible."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":16,"outputTokens":4,"serverToolUsage":{},"totalTokens":20}}451 409 +{"metrics":{"latencyMs":496},"output":{"message":{"content":[{"text":"Complex, transformative, intelligent, adaptive, evolving, data-driven, autonomous, cognitive, revolutionary, impactful."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":16,"outputTokens":23,"serverToolUsage":{},"totalTokens":39}}451 412 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.amazon.nova-micro-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -92,13 +92,13 @@ Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK -Content-Length: 244 +Content-Length: 247 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:17:32 GMT -X-Amzn-Requestid: ab32e805-3672-4f3e-a8dd-3874b00d4c00 +Date: Tue, 03 Mar 2026 15:43:59 GMT +X-Amzn-Requestid: f2f1d7b1-a5be-4008-bae3-c8cf95cb4b44 -{"metrics":{"latencyMs":256},"output":{"message":{"content":[{"text":"AI mimics human thinking to solve problems."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":16,"outputTokens":9,"serverToolUsage":{},"totalTokens":25}}468 546 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-5-20251101-v1%3A0/converse HTTP/1.1 +{"metrics":{"latencyMs":418},"output":{"message":{"content":[{"text":"Machines learning from data to make decisions."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":16,"outputTokens":9,"serverToolUsage":{},"totalTokens":25}}455 546 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-6-v1/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr Content-Length: 166 @@ -108,10 +108,38 @@ Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK Content-Length: 381 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:17:38 GMT -X-Amzn-Requestid: 48239999-d9d4-4687-998c-75b36e7207b1 +Date: Tue, 03 Mar 2026 15:44:07 GMT +X-Amzn-Requestid: e70f40d6-0fbf-40b1-8e87-d35e26abbc5a -{"metrics":{"latencyMs":4809},"output":{"message":{"content":[{"text":"AI: Machines learning to perform tasks requiring human intelligence."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":24,"outputTokens":15,"serverToolUsage":{},"totalTokens":39}}469 534 +{"metrics":{"latencyMs":1975},"output":{"message":{"content":[{"text":"Machines learning to think, decide, and solve problems autonomously."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":25,"outputTokens":17,"serverToolUsage":{},"totalTokens":42}}454 541 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 166 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK +Content-Length: 376 +Content-Type: application/json +Date: Tue, 03 Mar 2026 15:44:15 GMT +X-Amzn-Requestid: ab454da7-ab07-45cf-88f1-f6691989d084 + +{"metrics":{"latencyMs":1321},"output":{"message":{"content":[{"text":"**AI: machines learning to think, decide, and solve problems.**"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":25,"outputTokens":17,"serverToolUsage":{},"totalTokens":42}}468 537 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-5-20251101-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 166 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK +Content-Length: 372 +Content-Type: application/json +Date: Tue, 03 Mar 2026 15:44:23 GMT +X-Amzn-Requestid: 786f9a95-2326-4dc5-aa90-88d9a98844d2 + +{"metrics":{"latencyMs":2127},"output":{"message":{"content":[{"text":"AI: Machines learning to think, reason, and solve problems."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":24,"outputTokens":17,"serverToolUsage":{},"totalTokens":41}}469 534 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-haiku-4-5-20251001-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -122,10 +150,10 @@ Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK Content-Length: 369 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:17:40 GMT -X-Amzn-Requestid: fce386f3-99dc-4bc5-8e26-d601be2ce18d +Date: Tue, 03 Mar 2026 15:44:30 GMT +X-Amzn-Requestid: 7eb4d70c-6229-4ded-a260-22a68215e3be -{"metrics":{"latencyMs":695},"output":{"message":{"content":[{"text":"Machines learning patterns to make intelligent decisions."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":24,"outputTokens":12,"serverToolUsage":{},"totalTokens":36}}470 544 +{"metrics":{"latencyMs":1005},"output":{"message":{"content":[{"text":"Machines learning patterns to perform intelligent tasks."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":24,"outputTokens":12,"serverToolUsage":{},"totalTokens":36}}470 543 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -134,12 +162,12 @@ Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK -Content-Length: 379 +Content-Length: 378 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:17:44 GMT -X-Amzn-Requestid: b4a51cca-78a1-4578-9534-2de0c39e56e7 +Date: Tue, 03 Mar 2026 15:44:38 GMT +X-Amzn-Requestid: 60fb3af7-b5e7-486b-a03e-aeea6ea2d772 -{"metrics":{"latencyMs":2773},"output":{"message":{"content":[{"text":"AI: machines that learn, reason, and solve problems intelligently."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":24,"outputTokens":17,"serverToolUsage":{},"totalTokens":41}}468 546 +{"metrics":{"latencyMs":1888},"output":{"message":{"content":[{"text":"AI: machines learning patterns to make decisions and predictions."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":24,"outputTokens":14,"serverToolUsage":{},"totalTokens":38}}468 546 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-1-20250805-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -150,24 +178,10 @@ Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK Content-Length: 381 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:17:49 GMT -X-Amzn-Requestid: 5555b23d-2a06-413a-b8ab-4a5766cbd873 +Date: Tue, 03 Mar 2026 15:44:48 GMT +X-Amzn-Requestid: f920bd52-15c8-4a5e-9cac-c2ee1d0663f1 -{"metrics":{"latencyMs":3557},"output":{"message":{"content":[{"text":"Machines learning patterns from data to perform tasks intelligently."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":24,"outputTokens":15,"serverToolUsage":{},"totalTokens":39}}466 549 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-20250514-v1%3A0/converse HTTP/1.1 -Host: bedrock-runtime.us-east-1.amazonaws.com -User-Agent: langchaingo-httprr -Content-Length: 166 -Authorization: AWS4-HMAC-SHA256 test-api-key -Content-Type: application/json - -{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK -Content-Length: 384 -Content-Type: application/json -Date: Fri, 23 Jan 2026 13:17:53 GMT -X-Amzn-Requestid: 52cc7114-2cd5-4f39-b8d2-0cd91897a87d - -{"metrics":{"latencyMs":3612},"output":{"message":{"content":[{"text":"Machines learning patterns from data to make predictions and decisions."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":24,"outputTokens":15,"serverToolUsage":{},"totalTokens":39}}468 541 +{"metrics":{"latencyMs":3803},"output":{"message":{"content":[{"text":"Machines learning patterns from data to perform tasks intelligently."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":24,"outputTokens":15,"serverToolUsage":{},"totalTokens":39}}468 551 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-20250514-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -175,41 +189,27 @@ Content-Length: 166 Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json -{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK -Content-Length: 376 -Content-Type: application/json -Date: Fri, 23 Jan 2026 13:17:56 GMT -X-Amzn-Requestid: 541a16a6-f1ca-4c44-8eea-a2199e7bcc45 - -{"metrics":{"latencyMs":1719},"output":{"message":{"content":[{"text":"Machines that learn patterns to make decisions and predictions."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":24,"outputTokens":14,"serverToolUsage":{},"totalTokens":38}}470 564 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-7-sonnet-20250219-v1%3A0/converse HTTP/1.1 -Host: bedrock-runtime.us-east-1.amazonaws.com -User-Agent: langchaingo-httprr -Content-Length: 166 -Authorization: AWS4-HMAC-SHA256 test-api-key -Content-Type: application/json - -{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK -Content-Length: 399 -Content-Type: application/json -Date: Fri, 23 Jan 2026 13:17:58 GMT -X-Amzn-Requestid: f96ceeb1-f207-4b80-951f-36ed63a43874 - -{"metrics":{"latencyMs":878},"output":{"message":{"content":[{"text":"AI: Computer systems mimicking human intelligence through learning and decision-making."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":24,"outputTokens":18,"serverToolUsage":{},"totalTokens":42}}469 551 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-5-haiku-20241022-v1%3A0/converse HTTP/1.1 -Host: bedrock-runtime.us-east-1.amazonaws.com -User-Agent: langchaingo-httprr -Content-Length: 166 -Authorization: AWS4-HMAC-SHA256 test-api-key -Content-Type: application/json - {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK Content-Length: 386 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:18:01 GMT -X-Amzn-Requestid: 82864f82-2ab1-4066-9a5b-9ce4897f2e99 +Date: Tue, 03 Mar 2026 15:44:57 GMT +X-Amzn-Requestid: 68d35b70-5b56-4d54-99c9-7a877062d70c -{"metrics":{"latencyMs":966},"output":{"message":{"content":[{"text":"Machines learning and making decisions like intelligent, thinking systems."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":24,"outputTokens":15,"serverToolUsage":{},"totalTokens":39}}447 424 +{"metrics":{"latencyMs":2190},"output":{"message":{"content":[{"text":"Computer systems that mimic human thinking and decision-making abilities."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":24,"outputTokens":16,"serverToolUsage":{},"totalTokens":40}}469 535 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-5-haiku-20241022-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 166 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK +Content-Length: 370 +Content-Type: application/json +Date: Tue, 03 Mar 2026 15:45:04 GMT +X-Amzn-Requestid: 07d7cd57-2880-4d10-83c4-fdf13d51709e + +{"metrics":{"latencyMs":885},"output":{"message":{"content":[{"text":"Machines learning to think and solve problems like humans."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":24,"outputTokens":14,"serverToolUsage":{},"totalTokens":38}}447 454 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/cohere.command-r-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -218,12 +218,12 @@ Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK -Content-Length: 259 +Content-Length: 289 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:18:02 GMT -X-Amzn-Requestid: 5e2b4f8a-b101-42ce-91cd-e84c7f2afce5 +Date: Tue, 03 Mar 2026 15:45:10 GMT +X-Amzn-Requestid: 9c11e78a-9a29-450e-8111-94e2b0c07026 -{"metrics":{"latencyMs":206},"output":{"message":{"content":[{"text":"AI is the intelligence exhibited by machines or software."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":16,"outputTokens":10,"serverToolUsage":{},"totalTokens":26}}452 430 +{"metrics":{"latencyMs":280},"output":{"message":{"content":[{"text":"AI is the simulation of human intelligence in machines programmed to think like humans."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":16,"outputTokens":15,"serverToolUsage":{},"totalTokens":31}}452 422 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/cohere.command-r-plus-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -232,12 +232,12 @@ Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK -Content-Length: 265 +Content-Length: 257 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:18:03 GMT -X-Amzn-Requestid: 78373a09-9cba-46c8-beb0-02e09582d533 +Date: Tue, 03 Mar 2026 15:45:17 GMT +X-Amzn-Requestid: d4040238-b2db-4fa2-8f97-939eddd4fa6c -{"metrics":{"latencyMs":347},"output":{"message":{"content":[{"text":"AI is intelligent automation with machine learning capabilities."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":16,"outputTokens":9,"serverToolUsage":{},"totalTokens":25}}460 390 +{"metrics":{"latencyMs":375},"output":{"message":{"content":[{"text":"AI is the simulation of human intelligence by machines."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":16,"outputTokens":10,"serverToolUsage":{},"totalTokens":26}}460 390 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.meta.llama3-3-70b-instruct-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -248,10 +248,10 @@ Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK Content-Length: 225 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:18:05 GMT -X-Amzn-Requestid: 67d109c5-1970-4f20-9b0e-755b0929a512 +Date: Tue, 03 Mar 2026 15:45:23 GMT +X-Amzn-Requestid: 6fa697c4-75d7-4f06-b649-4c43177b8bb8 -{"metrics":{"latencyMs":236},"output":{"message":{"content":[{"text":"Artificial Intelligence."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":51,"outputTokens":5,"serverToolUsage":{},"totalTokens":56}}460 438 +{"metrics":{"latencyMs":217},"output":{"message":{"content":[{"text":"Artificial Intelligence."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":51,"outputTokens":5,"serverToolUsage":{},"totalTokens":56}}460 438 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.meta.llama3-1-70b-instruct-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -262,10 +262,10 @@ Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK Content-Length: 273 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:18:07 GMT -X-Amzn-Requestid: 3c114bc2-f0d3-44ff-b09c-6a98b810b0e9 +Date: Tue, 03 Mar 2026 15:45:30 GMT +X-Amzn-Requestid: 61c063ca-c56e-4498-bfbd-14a0a3051706 -{"metrics":{"latencyMs":848},"output":{"message":{"content":[{"text":"\n\nArtificial Intelligence: Machines that think and learn like humans."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":30,"outputTokens":14,"serverToolUsage":{},"totalTokens":44}}455 432 +{"metrics":{"latencyMs":938},"output":{"message":{"content":[{"text":"\n\nArtificial Intelligence: Machines that think and learn like humans."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":30,"outputTokens":14,"serverToolUsage":{},"totalTokens":44}}455 428 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/meta.llama3-70b-instruct-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -274,12 +274,12 @@ Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK -Content-Length: 267 +Content-Length: 263 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:18:08 GMT -X-Amzn-Requestid: 875c5ef7-2d76-484b-9c6b-38e953a1484c +Date: Tue, 03 Mar 2026 15:45:37 GMT +X-Amzn-Requestid: 0e4760b6-825c-4547-a5f6-44c71cbdbbf6 -{"metrics":{"latencyMs":480},"output":{"message":{"content":[{"text":"\n\nIntelligent machines that learn, reason, and act like humans."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":30,"outputTokens":15,"serverToolUsage":{},"totalTokens":45}}454 438 +{"metrics":{"latencyMs":435},"output":{"message":{"content":[{"text":"\n\nIntelligent machines that think and learn like humans do."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":30,"outputTokens":13,"serverToolUsage":{},"totalTokens":43}}454 438 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/meta.llama3-8b-instruct-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -290,10 +290,10 @@ Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK Content-Length: 273 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:18:10 GMT -X-Amzn-Requestid: 34dfd385-4249-46a0-9a81-585036091fcb +Date: Tue, 03 Mar 2026 15:45:43 GMT +X-Amzn-Requestid: 6c6a53ba-9b53-4980-9e9e-462ce9043b2e -{"metrics":{"latencyMs":278},"output":{"message":{"content":[{"text":"\n\nArtificial intelligence: machines that think and learn like humans."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":30,"outputTokens":14,"serverToolUsage":{},"totalTokens":44}}445 2633 +{"metrics":{"latencyMs":251},"output":{"message":{"content":[{"text":"\n\nArtificial Intelligence: Machines that think and learn like humans."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":30,"outputTokens":14,"serverToolUsage":{},"totalTokens":44}}445 2382 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.deepseek.r1-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -302,9 +302,219 @@ Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK -Content-Length: 2467 +Content-Length: 2216 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:18:14 GMT -X-Amzn-Requestid: d7bf9ada-1134-4601-a654-f4ac83794262 +Date: Tue, 03 Mar 2026 15:45:52 GMT +X-Amzn-Requestid: 96e5d6f1-86ed-40e2-a46f-0b405012ae74 -{"metrics":{"latencyMs":2904},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"text":"Okay, the user wants me to explain AI in 10 words or less. Let me start by recalling what AI stands for. AI is Artificial Intelligence, which involves machines simulating human intelligence. But how to condense that into a concise definition?\n\nI need to capture the essence: machines performing tasks that typically require human intelligence. Maybe words like \"machines,\" \"mimic,\" \"human intelligence,\" \"tasks.\" Let me count. \"Machines mimicking human intelligence to perform tasks.\" That's 8 words. Perfect. But wait, does that cover learning and problem-solving? Maybe \"machines simulating human intelligence to solve problems.\" Hmm, \"simulating\" might be better than \"mimicking.\" Let me check synonyms. \"Imitate,\" \"replicate,\" \"emulate.\" \"Simulating\" is accurate. \n\nAlternatively, \"Computer systems performing tasks requiring human intelligence.\" That's 9 words. But \"computer systems\" might be too narrow. AI can be in robots, software, etc. \"Machines\" is broader. Also, should I include learning? Maybe \"Machines learning and performing human-like tasks.\" But that's 8 words. \"Learning\" is a key aspect. However, the original answer I thought of was \"Machines simulating human intelligence to perform tasks.\" That's concise and covers the main points. Let me verify the word count. 1. Machines 2. simulating 3. human 4. intelligence 5. to 6. perform 7. tasks. Seven words. Wait, that's only seven. Did I miscount earlier? Let me check again. \"Machines mimicking human intelligence to perform tasks.\" That's 8 words. Hmm, maybe the user's example answer is different. Wait, the user's example answer is \"Machines simulating human intelligence to perform tasks.\" Let me count again. Machines (1), simulating (2), human (3), intelligence (4), to (5), perform (6), tasks (7). So seven words. But the user asked for 10 words or less. So that's acceptable. But maybe the user's example answer was different. Wait, in the initial prompt, the user's example answer is \"Explain AI in 10 words or less. AI: Machines simulating human intelligence to perform tasks.\" So that's 7 words. So the user's example answer is 7 words. So the answer is correct. But maybe I can make it even"}}}],"role":"assistant"}},"stopReason":"max_tokens","usage":{"inputTokens":20,"outputTokens":508,"serverToolUsage":{},"totalTokens":528}} \ No newline at end of file +{"metrics":{"latencyMs":3015},"output":{"message":{"content":[{"text":"\n\nAI: Computer systems performing tasks requiring human intelligence."},{"reasoningContent":{"reasoningText":{"text":"Okay, the user wants me to explain AI in 10 words or less. Let me start by recalling what AI actually is. AI stands for Artificial Intelligence, which involves machines simulating human intelligence. But how to condense that into a concise definition?\n\nHmm, maybe focus on the core aspects: machines performing tasks that typically require human intelligence. But that's a bit long. Let me count the words. \"Machines performing tasks requiring human intelligence.\" That's 7 words. Good, but maybe \"simulating\" instead of \"performing\"? \"Machines simulating human intelligence to perform tasks.\" Still 8 words. Maybe \"Systems that mimic human intelligence to solve problems.\" 10 words exactly. Wait, \"mimic\" might not be the best term. Some people argue AI doesn't mimic but uses different methods. Maybe \"Systems designed to think and learn like humans.\" But that's 10 words. Alternatively, \"Computer systems performing tasks needing human intelligence.\" 9 words. Maybe add \"learning\" in there. \"Machines learning and performing human-like tasks intelligently.\" 9 words. Or \"Technology enabling machines to think and act intelligently.\" 9 words. The user might want to include aspects like learning, problem-solving, decision-making. How about \"AI: Machines designed to learn, reason, and act autonomously.\" 10 words. That works. Let me check synonyms. \"Autonomously\" might be better than \"intelligently.\" Alternatively, \"AI simulates human intelligence in machines to solve problems.\" 10 words. But \"simulates\" is accurate. Another angle: \"Computer systems that can perform tasks requiring human intelligence.\" 10 words. That's from the standard definition. Yeah, that's solid. Let me confirm the word count. \"Computer systems that perform tasks requiring human intelligence.\" 10 words. Perfect. That's concise and covers the essence without jargon.\n"}}}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":20,"outputTokens":404,"serverToolUsage":{},"totalTokens":424}}437 440 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/deepseek.v3.2/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 166 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK +Content-Length: 275 +Content-Type: application/json +Date: Tue, 03 Mar 2026 15:46:00 GMT +X-Amzn-Requestid: 07a9b8cf-030a-4817-aced-a7b1267f5414 + +{"metrics":{"latencyMs":1656},"output":{"message":{"content":[{"text":"AI is machines performing tasks that usually require human intelligence."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":19,"outputTokens":12,"serverToolUsage":{},"totalTokens":31}}449 1049 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/openai.gpt-oss-120b-1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 166 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK +Content-Length: 884 +Content-Type: application/json +Date: Tue, 03 Mar 2026 15:46:07 GMT +X-Amzn-Requestid: d95bb073-8439-45b2-8460-c18735dcc616 + +{"metrics":{"latencyMs":601},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"text":"We need to answer: \"Explain AI in 10 words or less.\" So a short phrase with up to 10 words. Provide perhaps 9 words: \"Machines that learn, reason, and act like intelligent humans.\" Count words: Machines(1) that2 learn,3 reason,4 and5 act6 like7 intelligent8 humans9. That's 9 words, fits. Could be 10 words: \"Computational systems that learn, reason, adapt, and perform intelligent tasks.\" Count: Computational1 systems2 that3 learn,4 reason,5 adapt,6 and7 perform8 intelligent9 tasks10. That's exactly 10. Provide one. Let's answer succinctly."}}},{"text":"Computational systems that learn, reason, adapt, and perform intelligent tasks."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":84,"outputTokens":164,"serverToolUsage":{},"totalTokens":248}}448 1414 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/openai.gpt-oss-20b-1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 166 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK +Content-Length: 1248 +Content-Type: application/json +Date: Tue, 03 Mar 2026 15:46:14 GMT +X-Amzn-Requestid: a793c430-a095-4b91-a8ec-610fb48c78e1 + +{"metrics":{"latencyMs":861},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"text":"We need to answer the user request: \"Explain AI in 10 words or less.\" This is a simple request. Provide a concise explanation in 10 words or less. Possibly: \"Intelligent automation simulates human cognition, learning, reasoning, problem-solving.\" Count words: \"Intelligent(1) automation(2) simulates(3) human(4) cognition,(5) learning,(6) reasoning,(7) problem-solving(8). That's 8 words. Satisfies. Or \"Machines mimic human thinking, solving tasks autonomously.\" Count: Machines(1) mimic(2) human(3) thinking,(4) solving(5) tasks(6) autonomously(7). 7 words. That's fine. The user just wants something like that. Provide that answer. Make sure to stay within 10 words inclusive. Also mention AI is about making machines act intelligently. So answer: \"Machines mimic human thinking, solving tasks independently.\" Count: Machines(1) mimic(2) human(3) thinking,(4) solving(5) tasks(6) independently(7). 7 words.\n\nThus output."}}},{"text":"Machines mimic human thinking to solve tasks independently."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":84,"outputTokens":252,"serverToolUsage":{},"totalTokens":336}}447 424 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/qwen.qwen3-next-80b-a3b/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 166 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK +Content-Length: 259 +Content-Type: application/json +Date: Tue, 03 Mar 2026 15:46:20 GMT +X-Amzn-Requestid: 8c39cd13-bc27-41dc-9409-5b76b28b8417 + +{"metrics":{"latencyMs":535},"output":{"message":{"content":[{"text":"Computers learning to think, decide, and act like humans."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":30,"outputTokens":14,"serverToolUsage":{},"totalTokens":44}}447 415 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/qwen.qwen3-vl-235b-a22b/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 166 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK +Content-Length: 250 +Content-Type: application/json +Date: Tue, 03 Mar 2026 15:46:27 GMT +X-Amzn-Requestid: 11f09415-edc9-4a65-98f8-eb65b3c578fa + +{"metrics":{"latencyMs":426},"output":{"message":{"content":[{"text":"Machines that learn, think, and act like humans."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":30,"outputTokens":13,"serverToolUsage":{},"totalTokens":43}}445 476 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/qwen.qwen3-32b-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 166 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK +Content-Length: 311 +Content-Type: application/json +Date: Tue, 03 Mar 2026 15:46:33 GMT +X-Amzn-Requestid: 17020819-255a-4546-a197-c7b7e9a0aee8 + +{"metrics":{"latencyMs":232},"output":{"message":{"content":[{"text":"Artificial Intelligence: Machine systems designed to mimic human intelligence and perform tasks autonomously."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":34,"outputTokens":18,"serverToolUsage":{},"totalTokens":52}}455 464 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/qwen.qwen3-coder-30b-a3b-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 166 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK +Content-Length: 299 +Content-Type: application/json +Date: Tue, 03 Mar 2026 15:46:41 GMT +X-Amzn-Requestid: ccfe8200-4278-4fa8-a624-473210d4741f + +{"metrics":{"latencyMs":1274},"output":{"message":{"content":[{"text":"Artificial intelligence mimics human cognition through data-driven learning and decision-making."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":30,"outputTokens":16,"serverToolUsage":{},"totalTokens":46}}445 445 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/qwen.qwen3-coder-next/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 166 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK +Content-Length: 280 +Content-Type: application/json +Date: Tue, 03 Mar 2026 15:46:47 GMT +X-Amzn-Requestid: 0c919627-e4e1-48eb-8db3-92bae02f807a + +{"metrics":{"latencyMs":398},"output":{"message":{"content":[{"text":"AI: Machines that mimic human intelligence—learn, reason, perceive, and act."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":30,"outputTokens":18,"serverToolUsage":{},"totalTokens":48}}461 431 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/mistral.mistral-large-3-675b-instruct/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 166 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK +Content-Length: 266 +Content-Type: application/json +Date: Tue, 03 Mar 2026 15:46:54 GMT +X-Amzn-Requestid: cb8d40f7-f514-4af8-8413-1e3c2b6ac23e + +{"metrics":{"latencyMs":264},"output":{"message":{"content":[{"text":"Machines mimicking human intelligence for problem-solving tasks."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":22,"outputTokens":12,"serverToolUsage":{},"totalTokens":34}}452 423 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/mistral.magistral-small-2509/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 166 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK +Content-Length: 258 +Content-Type: application/json +Date: Tue, 03 Mar 2026 15:47:00 GMT +X-Amzn-Requestid: 27ea9d71-2af1-4ef4-b2ef-67308520534e + +{"metrics":{"latencyMs":459},"output":{"message":{"content":[{"text":"\"AI: Machines learning, mimicking human intelligence.\""}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":22,"outputTokens":12,"serverToolUsage":{},"totalTokens":34}}457 412 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/mistral.mistral-large-2402-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 166 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK +Content-Length: 247 +Content-Type: application/json +Date: Tue, 03 Mar 2026 15:47:07 GMT +X-Amzn-Requestid: bcaaedd4-45ad-4ca0-8450-285c256024b7 + +{"metrics":{"latencyMs":309},"output":{"message":{"content":[{"text":"AI is a machine mimicking human intelligence."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":22,"outputTokens":10,"serverToolUsage":{},"totalTokens":32}}444 425 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/moonshotai.kimi-k2.5/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 166 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK +Content-Length: 260 +Content-Type: application/json +Date: Tue, 03 Mar 2026 15:47:13 GMT +X-Amzn-Requestid: 3d9b25fe-e861-4b3f-93ff-2244a3e1bb34 + +{"metrics":{"latencyMs":483},"output":{"message":{"content":[{"text":" Machines learning patterns to predict, decide, or create."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":28,"outputTokens":13,"serverToolUsage":{},"totalTokens":41}}449 2673 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/moonshot.kimi-k2-thinking/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 166 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK +Content-Length: 2507 +Content-Type: application/json +Date: Tue, 03 Mar 2026 15:47:41 GMT +X-Amzn-Requestid: 4a56964c-b626-43b8-aa10-36482312d8d9 + +{"metrics":{"latencyMs":21116},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"text":" The user wants me to explain AI in 10 words or less.\n This is a very concise request. I need to distill the essence of AI into a short phrase.\n What is AI? It's about machines mimicking human intelligence.\n Key concepts: machines, learning, intelligence, problem-solving, automation.\n\n Let me try some options:\n - \"Machines that learn and think like humans.\" (7 words) - This is good, but \"think like humans\" is debatable and not always accurate.\n - \"Machine learning and problem-solving.\" (4 words) - A bit too technical and narrow.\n - \"Computers mimicking human intelligence.\" (4 words) - Simple and direct.\n - \"Teaching machines to learn and reason.\" (6 words) - Uses \"teaching,\" which is a good analogy.\n - \"Simulating human intelligence in computers.\" (5 words) - Similar to the previous one, maybe more accurate.\n - \"Machines performing tasks requiring human intelligence.\" (6 words) - This is a definition often used. It's accurate.\n - \"Intelligence demonstrated by machines.\" (4 words) - Very short, but maybe too vague.\n - \"Making computers smart.\" (3 words) - Too simplistic, almost childish.\n - \"Machine intelligence automating complex tasks.\" (5 words) - Good, covers automation.\n - \"Learning machines solving human-like problems.\" (5 words) - Okay.\n\n Let me reconsider the best one.\n \"Computers mimicking human intelligence.\" - 4 words. This is simple and covers the core idea. Is it perfect? No. AI doesn't always mimic human intelligence *exactly*, and sometimes it solves problems in very non-human ways. But as a high-level, sub-10-word explanation for a layperson, it's effective.\n\n Another option: \"Machines learning to perform intelligent tasks.\" 6 words. This is also good. It focuses on *learning* and *tasks* rather than just mimicry.\n\n How about: \"Simulating human cognition using computers.\" 4 words. \"Cognition\" might be too technical.\n\n \"Algorithms learning from data.\" 4 words. This is true for ML, but AI is broader (e.g., rule-based systems). But modern AI *is* mostly ML. This is also a very good, modern definition.\n\n Let's go back to the core. What is the simplest, most accurate, and most understandable explanation?\n - \""}}}],"role":"assistant"}},"stopReason":"max_tokens","usage":{"inputTokens":29,"outputTokens":512,"serverToolUsage":{},"totalTokens":541}}435 414 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/zai.glm-4.7/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 166 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK +Content-Length: 249 +Content-Type: application/json +Date: Tue, 03 Mar 2026 15:47:47 GMT +X-Amzn-Requestid: ea5cf569-be4f-4df6-a25f-1165790257fa + +{"metrics":{"latencyMs":294},"output":{"message":{"content":[{"text":"Machines learning to think and act like humans."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":22,"outputTokens":11,"serverToolUsage":{},"totalTokens":33}}441 389 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/zai.glm-4.7-flash/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 166 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Explain AI in 10 words or less."}],"role":"user"}],"system":[{"text":"You know all about AI."}]}HTTP/2.0 200 OK +Content-Length: 224 +Content-Type: application/json +Date: Tue, 03 Mar 2026 15:47:54 GMT +X-Amzn-Requestid: 85f1597a-b9e0-4a61-b051-d3e7f9ce9665 + +{"metrics":{"latencyMs":221},"output":{"message":{"content":[{"text":"Simulated intelligence."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":22,"outputTokens":5,"serverToolUsage":{},"totalTokens":27}} \ No newline at end of file diff --git a/llms/bedrock/testdata/TestAmazonReasoningConverseAPI.httprr b/llms/bedrock/testdata/TestAmazonReasoningConverseAPI.httprr index 6d003bba..30d10e2c 100644 --- a/llms/bedrock/testdata/TestAmazonReasoningConverseAPI.httprr +++ b/llms/bedrock/testdata/TestAmazonReasoningConverseAPI.httprr @@ -1,5 +1,33 @@ httprr trace v1 -542 1939 +529 1458 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-6-v1/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 240 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"additionalModelRequestFields":{"thinking":{"type":"enabled","budget_tokens":1024}},"inferenceConfig":{"maxTokens":4096},"messages":[{"content":[{"text":"Think step by step: What is 17 * 23? Show your reasoning process."}],"role":"user"}]}HTTP/2.0 200 OK +Content-Length: 1292 +Content-Type: application/json +Date: Tue, 03 Mar 2026 19:43:58 GMT +X-Amzn-Requestid: 4f15c605-66b9-4aed-99fa-3fecb1f3cba8 + +{"metrics":{"latencyMs":5338},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"signature":"EpQCCkgICxABGAIqQGN/vnBLGqecogCjXDmTXmDx81tdE9z+DMpyJOyx7nXoKV177dxUUMjSu1mvDkv58ejPnpwAWAbqTTaqFY3KhLISDC2iwcW4GDDlrU0Z5RoMTVQGHGe/Vv7CBBNIIjDx+8iCOZXDLtivQRwO8M35K2578+vr1Ai/0YKQ6JRNNAoCNMbjO26ddqF2XIirnoMqepOLopeDrQMuFJDrHv96E2Try3YE/zf+FSvmxhrjpFAIWiYR+CBGUdoENy2CchEYH8rYp50Hqrj3kZ9jTXC337KdmY3uH0NqpnXrjChwBKvRMCV+/QhxuoM5Pzb+MFPP7235J/7ZnB4Vb4iRjfT2IPvDIqAdtycyqNlVGAE=","text":"17 * 23\n\nLet me break this down step by step.\n\n17 * 23 = 17 * (20 + 3) = 17 * 20 + 17 * 3 = 340 + 51 = 391"}}},{"text":"# Multiplying 17 × 23\n\n## Breaking it down\n\nI'll use the distributive property to split this into easier parts:\n\n**17 × 23 = 17 × (20 + 3)**\n\n## Step-by-step calculations\n\n1. **17 × 20** = 340\n2. **17 × 3** = 51\n\n## Adding the partial products\n\n340 + 51 = **391**\n\n## Verification\n\n```\n 17\n × 23\n ----\n 51 ← (17 × 3)\n 340 ← (17 × 20)\n ----\n 391\n```\n\n**17 × 23 = 391**"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":55,"outputTokens":238,"serverToolUsage":{},"totalTokens":293}}528 1413 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 240 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"additionalModelRequestFields":{"thinking":{"type":"enabled","budget_tokens":1024}},"inferenceConfig":{"maxTokens":4096},"messages":[{"content":[{"text":"Think step by step: What is 17 * 23? Show your reasoning process."}],"role":"user"}]}HTTP/2.0 200 OK +Content-Length: 1247 +Content-Type: application/json +Date: Tue, 03 Mar 2026 19:44:14 GMT +X-Amzn-Requestid: 544dc82e-a7bb-4a91-a9ce-fabda9cb3064 + +{"metrics":{"latencyMs":4877},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"signature":"EvQBCkgICxABGAIqQN5oZ2H+jxOLvhrtwjkFbJgMNpfToY5q5/O8E8q/wsUdO72bG1QCSyQte6bbFH4rumBUzC4qXe6grPqa/FiBpHQSDMVxXY54wJ/GTJ0nohoMXLsKGhl6MmiwN6CKIjBlN+noh+L/wE9cjWQBU6w+dcZsE72iBNe/hhetNL+XbZ/Eg6PPOirOtxs14Y4SIjQqWnUqso/AGGDDLJmzZ1vl/fXWPfLFvkqAA9OqFWqmAWLR3m7T6/1yGCgShYWXif5RFN8apev+/1HnVHpyVv7gidmXlxU+RpPg1SJcAAo/F3v72QiuIfTLF/e/fBgB","text":"17 * 23\n\nI'll break this down:\n17 * 23 = 17 * 20 + 17 * 3\n= 340 + 51\n= 391"}}},{"text":"## Calculating 17 × 23\n\n### Method: Break Apart (Distributive Property)\n\n**Split 23 into 20 + 3:**\n\n| Step | Calculation | Result |\n|------|------------|--------|\n| 17 × 20 | 17 × 2 × 10 | 340 |\n| 17 × 3 | 17 × 3 | 51 |\n| **Add together** | 340 + 51 | **391** |\n\n### Verification (Standard Multiplication):\n```\n 17\n× 23\n-----\n 51 ← (17 × 3)\n+ 340 ← (17 × 20)\n-----\n 391\n```\n\n### ✅ Answer: 17 × 23 = **391**"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":55,"outputTokens":249,"serverToolUsage":{},"totalTokens":304}}542 2038 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-5-20251101-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -8,12 +36,26 @@ Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json {"additionalModelRequestFields":{"thinking":{"type":"enabled","budget_tokens":1024}},"inferenceConfig":{"maxTokens":4096},"messages":[{"content":[{"text":"Think step by step: What is 17 * 23? Show your reasoning process."}],"role":"user"}]}HTTP/2.0 200 OK -Content-Length: 1773 +Content-Length: 1872 Content-Type: application/json -Date: Fri, 23 Jan 2026 14:01:43 GMT -X-Amzn-Requestid: 8f2b1220-d8c5-46dd-ad32-8990baf2f8df +Date: Tue, 03 Mar 2026 19:44:31 GMT +X-Amzn-Requestid: e928d6f8-b309-49e0-9882-c3a8eda43439 -{"metrics":{"latencyMs":7272},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"signature":"EpUECkgICxABGAIqQH69Dv17/3nuqkw6XmAYcjMqZunNkAu8T2ORfcdNfldbgylOkuBEpjt57v3YCkKIOLj+d2KzXhjNeoTDGKb9CrwSDN6th2sZgSrjy9Zu2xoMTRXKBADbFaFaHuCBIjCxqMPEYcLpyktbLfqqzmp6pMNhlI5k+WHT4FtcDrAGwBOojDt5/PBrWaQvX0sTlzsq+gJzOTLvVNVeZGv5vjpndiGsK+HVkYrVTDvA7Y9TF91Moi+jJ5j+CPeO4lMuqFsond6pVDGpKQN/oso2VJzpmcFRPCaxDwjfz0GsmmXZh7LSPfd4RDl9GmTv3SGhSlrdYvZ8fj2JToTeBZ4b9QorjQPkPhLyoSCksQFT5HPoKuFAKcIdhx7GgPVWbOlmFOnfcSEiM9+cbM5Wal2RW2205C72SPSibVaGdVdwQUpF1SQFaz/vzLmZBuV+sQy+v/fG/hL81uq8YkjNj6ItgoeWy2ipjVfKVs6JlxHC/SCxCuefu3JOJseHIUSXwiTbNryOmLU5xhN1wbntk501FmCrsFQBmDe8ITyqIQUQOr1r+DSpBv9GSdH+EYuSWfj5txZDbmictMjzNm6v7ll3xshNl2ckB66JDKKK3itSWtEHGUVHun3wJrrXCBeqBB6etLT1fPxsV+mnLi+d7U0mysy4IE/cRtv6wpNL2JcCqd+QtgN887Y6+/VLSkUxEkgYAQ==","text":"I need to calculate 17 * 23. Let me break this down step by step.\n\nI can use the standard multiplication method or break it into easier parts.\n\nMethod 1: Breaking down the numbers\n17 * 23 = 17 * (20 + 3)\n= 17 * 20 + 17 * 3\n= 340 + 51\n= 391\n\nLet me verify with another approach:\n17 * 23 = (20 - 3) * 23\n= 20 * 23 - 3 * 23\n= 460 - 69\n= 391\n\nYes, the answer is 391."}}},{"text":"# Calculating 17 × 23\n\n## Breaking it into simpler parts\n\nI'll split 23 into (20 + 3) to make this easier:\n\n**Step 1:** Calculate 17 × 20\n- 17 × 20 = 340\n\n**Step 2:** Calculate 17 × 3\n- 17 × 3 = 51\n\n**Step 3:** Add the results\n- 340 + 51 = **391**\n\n## Answer: 17 × 23 = 391"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":55,"outputTokens":288,"serverToolUsage":{},"totalTokens":343}}544 2516 +{"metrics":{"latencyMs":5915},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"signature":"EpwECkgICxABGAIqQN3fdQ8wsZIz3w/v24CxB20FhHExj9qU3iaQOLbiL12tl2YmOge4OgeHVqiEhc/gbGcLY9YpST2fk9vxXJoMjNESDImFQeZGeovMnt75OxoMpcI2C4Nh0gnpp/qIIjBlO+hsBayR8rvBt3L8Tbn8JmPuinaV3cNerWAgfzoxbIv//j5WKDlqMTB5pn6Y5PcqgQM663SCzOjwXIZX+4L4T9ebpnXATqtcbObQi8ucsDzcK+cWf0emxS9C3ls7YpMOeKG9npIvmHlJlZmsyyw+J03xOn9QhRuV7gWZ6fzENx8JBZQDTQT0ZCPLNHKsz5OGKV9KmqehYoMIDliACLHPeTJOJbCVmHv3PTLbzf+a7P0lB7bFUAu0FHrMEXVv/nzh+l534kJKKg/6V7J6S8u+UyOD74aLMpqPFSmXkNs3i3m0+0bhG5cUoeMTHVXXs5wjA5VhEDG7jjiGyfKukecEOsS7/TXZDDf4dvLtKNuxqkQB7y1Imi9oGHSQzYxONJNLC8TEhhQqp/mW0ivwpu/g8r/RX2/5Y7RH7xfk2VEOXhF6rx2vd0en9ov5+jJUd12BRxx6YORlKjeky9oO1+YhSZw152ij/k/m2zUywgXnqaMy96n2Yd72v5iyISQNOrMNmJ3crFO0xquAJ6yeS5v6+X3uLq7boJqKSJhiYhBok5ztS/TIKwoSYIFqyLa66GPS8W2gGAE=","text":"I need to calculate 17 * 23. Let me break this down step by step.\n\nMethod 1: Standard multiplication\n17 * 23\n\nI can break this down as:\n17 * 23 = 17 * (20 + 3)\n= 17 * 20 + 17 * 3\n= 340 + 51\n= 391\n\nLet me verify with another method.\n\nMethod 2: Breaking down 17\n17 * 23 = (10 + 7) * 23\n= 10 * 23 + 7 * 23\n= 230 + 161\n= 391\n\nBoth methods give me 391, so the answer is 391."}}},{"text":"# Calculating 17 × 23\n\n## Step-by-Step Solution\n\nI'll break this into simpler parts using the distributive property.\n\n**Method: Break 23 into (20 + 3)**\n\n17 × 23 = 17 × (20 + 3)\n\n**Step 1:** Calculate 17 × 20\n- 17 × 20 = 340\n\n**Step 2:** Calculate 17 × 3\n- 17 × 3 = 51\n\n**Step 3:** Add the results\n- 340 + 51 = **391**\n\n## Answer: 17 × 23 = **391**"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":55,"outputTokens":331,"serverToolUsage":{},"totalTokens":386}}543 2085 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-haiku-4-5-20251001-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 240 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"additionalModelRequestFields":{"thinking":{"type":"enabled","budget_tokens":1024}},"inferenceConfig":{"maxTokens":4096},"messages":[{"content":[{"text":"Think step by step: What is 17 * 23? Show your reasoning process."}],"role":"user"}]}HTTP/2.0 200 OK +Content-Length: 1919 +Content-Type: application/json +Date: Tue, 03 Mar 2026 19:44:45 GMT +X-Amzn-Requestid: b3f26a3f-2ac3-4692-8c83-7b8042ac9a2e + +{"metrics":{"latencyMs":2560},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"signature":"ErIECkgICxABGAIqQF8y6aqbNjoVfr3g3hbtOd3OJUR4ffak4iCiJZB5Ah1s6iVEZ/ALetVtfvDl7+Hz2zIXxaPGR3zjx8xVe/TrpgMSDBhmLtm20Md/A7v97BoMuT/Bvcy0E97n1btkIjDwYu9Vvxk7Kvp/9LGR5X5DHNW/3LmQ9w8HXXDIBps1l+hOHOd3OQj/oeAq2QJpQBQqlwMmhUMfo4zSYgqNdGDcxTaR5Fu4UtTDRCDNUmI0gxQKNlxrbVs52CXDk39dWPFaneDRk08v3Y55UK+KDlEIt3/2Il9SPOS2LHsJrsCYWZEDfwLuhX6jDbH9sS8dn90VUK0CSuothFjkGEvVggJGS3UQaBMn+QNoLPYTnJqu3+7X4bJ44DPcCcl7fjlBSjMZpUH2TNxeSRC1MSvs+n/Fae0xhp0LmyRT7dEF5pADLufsfgVE50fhjHFsGnqnv8cPGlH28A4Q+2zcICKplQ4jaCb0KYROHWbmDAqMHPNMdeJKSLu93QGDMJZphvu8ZGErqD6CzuK9DM47V6WwrhgKGav/lYsX32ubzRq8KOrlVraFpXqTYGCSxxVyVi9FV+7h7P/OCDzjYPbhSP51i5+sZx9bnCfnUrgQdlctUAGw1EDM+fioFRBweUGeqcximekZaOXFJ4+UKbvQY/mL5rWEUYZWMVP9LlcUDSK0pHmqqvywoYKUxS8zFBLBu+shJ3i0RPbhpINLF8VzYRJdmTREk8wgRTnRsN++hBgB","text":"I need to calculate 17 * 23. Let me work through this step by step.\n\nMethod 1: Breaking it down using the distributive property\n17 * 23 = 17 * (20 + 3)\n= 17 * 20 + 17 * 3\n= 340 + 51\n= 391\n\nLet me verify this with another method to make sure.\n\nMethod 2: Another way to break it down\n17 * 23 = (10 + 7) * 23\n= 10 * 23 + 7 * 23\n= 230 + 161\n= 391\n\nBoth methods give me 391, so that's the answer."}}},{"text":"# Calculating 17 × 23\n\nI'll break this down using the distributive property:\n\n## Method 1: Split 23 into 20 + 3\n\n17 × 23 = 17 × (20 + 3)\n\n= (17 × 20) + (17 × 3)\n\n= 340 + 51\n\n= **391**\n\n## Verification using Method 2: Split 17 into 10 + 7\n\n17 × 23 = (10 + 7) × 23\n\n= (10 × 23) + (7 × 23)\n\n= 230 + 161\n\n= **391** ✓\n\n**Answer: 17 × 23 = 391**"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":55,"outputTokens":347,"serverToolUsage":{},"totalTokens":402}}544 2307 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -22,40 +64,12 @@ Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json {"additionalModelRequestFields":{"thinking":{"type":"enabled","budget_tokens":1024}},"inferenceConfig":{"maxTokens":4096},"messages":[{"content":[{"text":"Think step by step: What is 17 * 23? Show your reasoning process."}],"role":"user"}]}HTTP/2.0 200 OK -Content-Length: 2350 +Content-Length: 2141 Content-Type: application/json -Date: Fri, 23 Jan 2026 14:01:50 GMT -X-Amzn-Requestid: 6e8b3bd8-5914-4a74-bbf9-1b2dba5675d5 +Date: Tue, 03 Mar 2026 19:45:02 GMT +X-Amzn-Requestid: 2ea9fa52-4c35-4359-b565-d5cc58f4321e -{"metrics":{"latencyMs":5659},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"signature":"EqUFCkgICxABGAIqQPINXYxMeNgZBwXMLylqEffnwKWlyrItZ6k6XzA374XkyPynvsEPk3W28UolHsSCrzS1V6aU80+CbxDR+2IBizUSDI4HFk4GM8lJ3rhXyxoMH+D8xeDSCIppOvxFIjC1gwLzJBLytxAGxUeBuQtxfkVCjEOdZXtzmXkElexOJum5iRCeuj9NDuc3Z/ZF18gqigS2kgyIhPaxo9iYlFsdIJU+hz7W8ZlglvVAFVWAxlASXzTFFc/huh6tlB5w1pCk8ndMfjlKwkFIuBcXOKMtkN5sDd47cxLvlCqHTcxS8mu8gyxwAS5aXw4rhTvL+vA8SS7I1UTiNWPJ5c2wLLzhE9HeUrX8ntlqd/w2g0err8xvllCKrOHA3Xb2pDIIx5eF6LipjFwT7lXf2gaya5vYxWtH2RPpOKhO1L/o7kL4emJsXGeP7EluVcIfkvc/ojZTzuez5IeG1iTFzeczeIUUKyeoPhu7cte9fs9TFOghrTs66eZdZ3NaLODeLyrVCDNMpt2FmFsw+xM0ojNOzF7SrjexqgVSnGsYUEmvC0USD3pREpDlJPygAODMISSzN9lVD3fKESSQ60S/iF1QlXqbN37U1B/ssVGi6A6kYIDdzXpR23CFB+00nU2J0Y4MH/NtpBhl4xbmFIepvsM2RX7jBN5Rx6o3Cce1YEsqyLjoI/iQfVDGCILXg4kIz64y1ucScOY/cLoaNSDiqKNm/sv4H6egWOVIqO/x+B6G71BPX3hToT0AJQpAIc1E0VA+zgIq3Nf5ImbfgXnuRSXairWcfac+tOSvJPD793gedMWH8ITBrbIfogEO8dzE732fBfAHoEEepfcX1sbNaanOAvkyEBuCS//frlAmlh9hoZKBrOhUkUkbirYdS7/C7isYAQ==","text":"I need to calculate 17 * 23. Let me break this down step by step.\n\nI can use the distributive property to make this easier:\n17 * 23 = 17 * (20 + 3)\n = (17 * 20) + (17 * 3)\n\nLet me calculate each part:\n- 17 * 20 = 17 * 2 * 10 = 34 * 10 = 340\n- 17 * 3 = 51\n\nSo: 340 + 51 = 391\n\nLet me verify this another way:\n23 * 17 = 23 * (10 + 7)\n = (23 * 10) + (23 * 7)\n = 230 + (23 * 7)\n\n23 * 7 = (20 * 7) + (3 * 7) = 140 + 21 = 161\n\nSo: 230 + 161 = 391\n\nBoth methods give me 391, so that's correct."}}},{"text":"# Calculating 17 × 23\n\nI'll break this down using the distributive property:\n\n## Method: Break 23 into 20 + 3\n\n**17 × 23 = 17 × (20 + 3)**\n\nThis splits into two easier multiplications:\n- 17 × 20 = 340\n- 17 × 3 = 51\n\n**Add them together:**\n340 + 51 = **391**\n\n## Verification using a different breakdown:\n\nLet me verify by breaking down 17 instead (as 10 + 7):\n\n**23 × 17 = 23 × (10 + 7)**\n- 23 × 10 = 230\n- 23 × 7 = 161\n\n**Add them together:**\n230 + 161 = **391** ✓\n\n**Answer: 17 × 23 = 391**"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":55,"outputTokens":478,"serverToolUsage":{},"totalTokens":533}}542 2068 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-1-20250805-v1%3A0/converse HTTP/1.1 -Host: bedrock-runtime.us-east-1.amazonaws.com -User-Agent: langchaingo-httprr -Content-Length: 240 -Authorization: AWS4-HMAC-SHA256 test-api-key -Content-Type: application/json - -{"additionalModelRequestFields":{"thinking":{"type":"enabled","budget_tokens":1024}},"inferenceConfig":{"maxTokens":4096},"messages":[{"content":[{"text":"Think step by step: What is 17 * 23? Show your reasoning process."}],"role":"user"}]}HTTP/2.0 200 OK -Content-Length: 1902 -Content-Type: application/json -Date: Fri, 23 Jan 2026 14:02:08 GMT -X-Amzn-Requestid: 45222b32-fbd0-4398-98cc-f9b098750286 - -{"metrics":{"latencyMs":17761},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"signature":"EvUDCkgICxABGAIqQNdlQQKdiOUOh7R7bEGA4/HLx/A6e+wFpJMPFh4ni+TgUCyROIqXkM3fIMLfmfNUMhvHLW7ulcSH/N/m1TW+m4ASDKEZ/VcJxflCoLIE0BoMDopa1lrkKKGtcK2UIjCnBu0ekrHnrfp/SVgoD7orVH++8z91s+Z6gAT+EZl2CNhZKhXSV54do3QYTTmek/Iq2gJdGaorERUEKB3UPKdemTzvfxgdZerZ6TDf0MFSkdmNKVkPTYghSFS2JyH0W8gQ27XxFobBcrqfPYRaucAIntwMTjpRAzlqJ7yrlemFs/0hym8cc6e1NtwlCvy8oJiTo1UlzCtHjyVagmgIekJmeFdPfDKFuXMGxQm5Ebkb57H2fB3hSdg2wZC/ak9Okvt2v6p4ckK3R5uNXHIWKNJsAIFwtu9RfxR76hCiZDmI2lQ0p2KkfC5XAtI2OD5rRTP2UW/yugC/zGdwonmT+1i4wO2MgqPJWqPWohIk2h6A+vgMSIiMuSpB77Cuy6m9Pu/QyVYyBMPamLMfhikBr/h4PFKop71MnqQmnAswLuUvBMQFJuMhdz/AvOu9eCFu7P1Pzi/LpSqou1wCrwqAu+MxkjVVaWyZYfd7zotUfQjmuXqPuUYxpWDrGMbyHMZgM7RsPL38FWEFSwjOOA3eGAE=","text":"I need to calculate 17 * 23 step by step.\n\nLet me break this down using the distributive property:\n\n17 * 23 = 17 * (20 + 3)\n = (17 * 20) + (17 * 3)\n = 340 + 51\n = 391\n\nLet me verify this another way:\n23 * 17 = 23 * (10 + 7)\n = (23 * 10) + (23 * 7)\n = 230 + 161\n = 391\n\nGood, both methods give me 391."}}},{"text":"I'll calculate 17 × 23 step by step using the distributive property.\n\n**Method 1: Breaking down 23**\n- 17 × 23 = 17 × (20 + 3)\n- = (17 × 20) + (17 × 3)\n- = 340 + 51\n- = 391\n\nLet me show the sub-calculations:\n- 17 × 20 = 17 × 2 × 10 = 34 × 10 = 340\n- 17 × 3 = 51\n\n**Method 2: Let me verify by breaking down 17**\n- 23 × 17 = 23 × (10 + 7)\n- = (23 × 10) + (23 × 7)\n- = 230 + 161\n- = 391\n\nSub-calculations:\n- 23 × 10 = 230\n- 23 × 7 = 161\n\n**Answer: 17 × 23 = 391**"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":55,"outputTokens":406,"serverToolUsage":{},"totalTokens":461}}540 2554 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-20250514-v1%3A0/converse HTTP/1.1 -Host: bedrock-runtime.us-east-1.amazonaws.com -User-Agent: langchaingo-httprr -Content-Length: 240 -Authorization: AWS4-HMAC-SHA256 test-api-key -Content-Type: application/json - -{"additionalModelRequestFields":{"thinking":{"type":"enabled","budget_tokens":1024}},"inferenceConfig":{"maxTokens":4096},"messages":[{"content":[{"text":"Think step by step: What is 17 * 23? Show your reasoning process."}],"role":"user"}]}HTTP/2.0 200 OK -Content-Length: 2388 -Content-Type: application/json -Date: Fri, 23 Jan 2026 14:02:31 GMT -X-Amzn-Requestid: 53cb3e73-9087-411a-b588-9e9b30bf7671 - -{"metrics":{"latencyMs":21668},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"signature":"Er8FCkgICxABGAIqQHf4WKannOf0uOwOwsPvdrW7Dwwt38BDhakw/pJm9G4ehcEdHbyfvQdSYFVc3radRGaw/2fkRIUksgLlM/oQmywSDCwYz7xyG75qDODKaRoMgt2pB/kzJsavMswcIjCSbR+KYYD2LelQ1YubfzwBdXRx6jZth0EkqOrUvLqnhn0DHSyzgu3YaurONGTipOUqpARPgibP/RA/udm9vwy8xRX5h/Cu5k4Uv0Hm/lX0pBWAxMHmqOR5vWDz8AvL0JPST2oMTKDE66Ekdv4QkQCeQULDF2b7OOvRVy+I/R2tXaQlXVkX/b90A7pONbNLmpL/jG2b0kHdBwIQzneki8m/WTIiNVCa0hnFiYSLYCQmie7mVn8n+hi5LLdpNqKlnHzZYqIuqGldJAg9q1149DjGXVyQltmt2LNj29TRLb1vlT7GWYc9Go011KzJfW/GjkD7ShWq/zjV1jjA6dfQP+3iDqcpvNpNWkzJ1ew+FPG+FpOTvB/hEiVTfLeKQfE9Q7V0J97FBN+ucXTjLZHl+ApWt6m9KX70HhvIl4m+1dnfu/6u8lVEsqjsl9cWxGPXipzzBXXi/CsSqaR37eJeYZUvjg73grpWg9CM9EasozW0So7gV3qS3OQWBPO44EXHibKFawv+Ot2iaJfKJUNoeCh3PMDrAphsITYV/5pDZWsZUuYTfd3Uc0zXtkqq20X2AVK49wxl2QLVXJ1DmkUp+PbBAXxgQ2GqGqzUjw1rK9oeY0NS66vqFeN6l+5dctkUEUYp6Z64lKCQdvdeHFtEywe+TfUX0BLxo1e9fYL5mZMa68SkVqgIRlCLrKDm8/NJZjOrQvo9d1Y50WTUQ7URKkL7t0arNVagAv1Wf/eWlcr/I/R0xHy5Ml+wmrLmeW9pLwa4NcCHQqe3zP5orHeGxQwD/1E78OJQ0BgB","text":"I need to calculate 17 * 23 step by step.\n\nI can break this down in several ways. Let me use the standard multiplication method:\n\n17 * 23 = ?\n\nI can break 23 into 20 + 3:\n17 * 23 = 17 * (20 + 3)\n= 17 * 20 + 17 * 3\n= 340 + 51\n= 391\n\nLet me verify this another way. I can break 17 into 10 + 7:\n17 * 23 = (10 + 7) * 23\n= 10 * 23 + 7 * 23\n= 230 + 161\n= 391\n\nGood, both methods give the same answer.\n\nLet me also verify using the standard multiplication algorithm:\n 17\n × 23\n ----\n 51 (17 × 3)\n 340 (17 × 20)\n ----\n 391"}}},{"text":"I'll solve 17 × 23 step by step using the distributive property.\n\n**Method 1: Breaking down 23**\n- 17 × 23 = 17 × (20 + 3)\n- = (17 × 20) + (17 × 3)\n- = 340 + 51\n- = 391\n\nLet me verify this with another approach:\n\n**Method 2: Breaking down 17**\n- 17 × 23 = (10 + 7) × 23\n- = (10 × 23) + (7 × 23)\n- = 230 + 161\n- = 391\n\n**Traditional multiplication check:**\n```\n 17\n × 23\n ----\n 51 (17 × 3)\n 340 (17 × 20)\n ----\n 391\n```\n\nTherefore, 17 × 23 = **391**"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":54,"outputTokens":466,"serverToolUsage":{},"totalTokens":520}}542 2397 +{"metrics":{"latencyMs":5932},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"signature":"EuMECkgICxABGAIqQC+KM9Ym1pLVdus5pR0yB0fftebblJJ0HSd4IJSXiMMTbaH5BL9n2hYit58Qcv2jHJJhA7XxUN5suHYO9CBcyjkSDPQBxPm3eLSW0J2WaxoM8h4pqJlNn1mThk4jIjDPoZgWs2lLt4yV11asp0lc1SeoUHY+Phscf/7UQY6bdTYOLDF7fVT6xvVQr6w/lCMqyANyKdMgv/gVGjpn+r7ujJ4v5dutcH0FU6MHLNphQmU9kyxEZxCDJsRCVspQWCn6H5j/j4BUVfab8rmm5sy2xpaAn7R3sWALlFC9yK7/7QE7W7GCqMHz15p4zICWxm0BppeDvJX20xVd3qMgMi2/oxCg+KRIkEwLhh3m7p16zpD8YXJpb+NkoWSgLYhpnnGgSCPiat2PT9xEDFmzRc6iiUBfmcnd47tlsFXcOFVGt4BlN4/1gJFlaMq+sZFvlCGN60r00ah2++4Htzss4sCzyGWfqTmI0Rv1QeMzpKShhsZFfPHf9ARGrpk/BKtLoThRS4z/j8RIh9PF+kFF5g0hhpGqG13dkWChv9B8dDUQgGC0Yyk9hjQfAMRPG/RTiDS/Qnbtu4S2z9XEnbc9cTZ7HHy3Ejma/9GlZ7z8BHIo+0O6sib1t6X+V3rE2eeLZreqINS/huwpDxKnGS9KmwwXcPwTV8dspfwulkEqE7piwcct8Xnz+1cK9oDmPWK5Dssg0L5U2YZ9ji2h8pznc6b5D3gK7ws0JEMwbZbPfuKW6gJG4QcQQTsCGaA33JpMrb3PP8TMgdoDRsa1IfsULxOmdDXANU0Kkcx2jLQYAQ==","text":"I need to calculate 17 * 23. Let me break this down step by step.\n\nMethod 1: Breaking down by place value\n17 * 23 = 17 * (20 + 3)\n= (17 * 20) + (17 * 3)\n= 340 + 51\n= 391\n\nLet me verify this with another method.\n\nMethod 2: Breaking down the first number\n17 * 23 = (10 + 7) * 23\n= (10 * 23) + (7 * 23)\n= 230 + 161\n= 391\n\nLet me double-check 7 * 23:\n7 * 23 = 7 * 20 + 7 * 3 = 140 + 21 = 161 ✓\n\nBoth methods give me 391, so that's the answer."}}},{"text":"# 17 × 23 = ?\n\nLet me solve this by breaking it down into easier parts:\n\n## Method: Split 23 into 20 + 3\n\n**17 × 23 = 17 × (20 + 3)**\n\n### Step 1: Multiply 17 × 20\n- 17 × 20 = 340\n\n### Step 2: Multiply 17 × 3\n- 17 × 3 = 51\n\n### Step 3: Add the results\n- 340 + 51 = **391**\n\n## Verification using another approach:\n\nBreaking down 17 instead: **(10 + 7) × 23**\n- 10 × 23 = 230\n- 7 × 23 = 161\n- 230 + 161 = **391** ✓\n\n**Answer: 17 × 23 = 391**"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":55,"outputTokens":435,"serverToolUsage":{},"totalTokens":490}}542 2420 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-20250514-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -64,13 +78,27 @@ Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json {"additionalModelRequestFields":{"thinking":{"type":"enabled","budget_tokens":1024}},"inferenceConfig":{"maxTokens":4096},"messages":[{"content":[{"text":"Think step by step: What is 17 * 23? Show your reasoning process."}],"role":"user"}]}HTTP/2.0 200 OK -Content-Length: 2231 +Content-Length: 2254 Content-Type: application/json -Date: Fri, 23 Jan 2026 14:02:38 GMT -X-Amzn-Requestid: 105068ba-2aa1-4727-aa1f-872f81b76078 +Date: Tue, 03 Mar 2026 19:45:17 GMT +X-Amzn-Requestid: 2a4265f1-c110-454b-97c8-3a82d3206689 -{"metrics":{"latencyMs":5222},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"signature":"EvwECkgICxABGAIqQN+UN1xiOQ1bWK1idzPcWpQNG21zA6YZr7nrx/YbpM812s/XGLLRWwijEde2cHJSVhBhUv9NkkZnT+VKuTHTFDUSDCJJdCPxjjQCZxWm2hoMfZqJFyLGvt+MTrr8IjAKgU9dNzRk+6enqbzBJkIwYqadGCkBGFfN1J4hxb3NYRv4NKpNOSUFq06AIPNnSEAq4QOanLNumRnjIPz0jnDSMm66BoBjB2o08j/xca7oS9nUXP9JyS/16e35JMF7ifw2YVJw0CFDBFaKCtRHW7NqZU2Ov1yH9T71fRNyksk6P7rnf0GoriUqKGfAtygHwi2deaAAbNSkK0ApbORY20CreQp4JkJJBZ6vB6RWdKaBpew3L7eNMmxJatQqLyTQUaHOUD4Hq1cmfhFNgAhz/E05Nb+XFuhrgIj4dWZvsSbf3IjJcTwtBKCbSCVQWZJwnm4P9JjqL9a6j4/Nzz+hKJUe8GaofT0gMCtggTJTV7yx/+XVWDn2IOV7GzqAWRVFIpBw7EG/v0bOFqtGM2+qsK8hrB10f5P20LhOlgt9460Uj2U6FOWwruG9Is7vzR6Jn+7hhiKFizEvq+6WJ+nZ5kl7xj8RtE1GE2APcXT8G3uauxT6Y6ZZSZz+T1Rru0nWQFFsutw5WVfWhGU4Pd9ik3xbBuKYEkBP0/ScWQFQFH8OiFsjQwdqnQbYYM9Nx6V7wMpzx5Z+G3km93VQ5fkdLVpXuDoAaE715MJLKRRiMNyFvkfkbIArr4CGL5j/x0HbqH7OVd5kiHUwS678gqo0v/NHTg8peZcXIPMuBcQCXimKYe61OPRXkhEYcugGZ+vn2IM9UqSrGAE=","text":"I need to calculate 17 * 23. Let me do this step by step using the standard multiplication method.\n\n17 * 23\n\nI can break this down using the distributive property:\n17 * 23 = 17 * (20 + 3) = 17 * 20 + 17 * 3\n\nLet me calculate each part:\n17 * 20 = 17 * 2 * 10 = 34 * 10 = 340\n17 * 3 = 51\n\nSo 17 * 23 = 340 + 51 = 391\n\nLet me double-check this using the standard algorithm:\n 17\n × 23\n ----\n 51 (17 × 3)\n 340 (17 × 20)\n ----\n 391\n\nYes, that's correct."}}},{"text":"I'll solve 17 × 23 step by step using the distributive property.\n\n**Step 1: Break down 23 into easier parts**\n23 = 20 + 3\n\n**Step 2: Apply the distributive property**\n17 × 23 = 17 × (20 + 3) = (17 × 20) + (17 × 3)\n\n**Step 3: Calculate each part**\n- 17 × 20 = 340\n- 17 × 3 = 51\n\n**Step 4: Add the results**\n340 + 51 = 391\n\n**Verification using standard multiplication:**\n```\n 17\n× 23\n-----\n 51 (17 × 3)\n 340 (17 × 20)\n-----\n 391\n```\n\nTherefore, **17 × 23 = 391**"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":54,"outputTokens":422,"serverToolUsage":{},"totalTokens":476}}544 1627 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-7-sonnet-20250219-v1%3A0/converse HTTP/1.1 +{"metrics":{"latencyMs":4404},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"signature":"EvoECkgICxABGAIqQDJCN0r3VW4DgDzE1eGzD/0807wS302MJ8p4CWBm8u5PO0tpnB3qhMOir7uZUcM9/gCPOh+VZW8Yf0KmidlfveoSDBci1uTLkBaYguFa3hoMj6dLB+T69bNGbz9OIjDOT+eSTNtkYvTu0pFaDcGncxu2z08oaN+Di0zMB+zb57bFxuHvbpjgaj4kTPLL84Iq3wOpru3kLYWUjkzrmDze32JsqRN9k987EbvxcMZ/0G21jiTSDJMuTu31HKyX39OTWsk8NNZCO1BItgihdhf0OhdtAmeC1Uqid/yYZYDP13uOuPb4ntrY5NHpAXoGpegryy87L/LN9YIIGE7LQgf1rU/X2RiDg96M4Qc81Iii1aM2PJb0Rw3oceuH1/jCK7pqOVTwGtIP4hIfc7H5m7XU4bPMLDgtiNtCU741NiHfSH915AcTun1LFDh5qtpjwV4IQW88/Wv+pGSnyLwhFjQTHmBJPwi3CJfToBLRuJNO+ZQPvy5NFMb4Sb5qZmJwCGnvZ57MYN1gKDK3w7CPwci4xNq2NZw/UmhUKLOvNza/17F5WJTFkG4UV3/VYYdVRN+UD51G5M6WRH9KugekBe6Od9sSw2CPFgy6Z906BhInHlHMbo+oTC4mpWspeu1alikgv1RkTI6FsjEAAkTV7MkraL1tn4KJLJ4syBZoZcRjPi7CnrI4gKD1ahUIKCEZr/g5Bq9bv92RjyAnH/a0r0xYW3sHj3aysRVJ4NQvZY+sp0QbRIImeH6gHPiBRXQ8nwsChmpkykkMwv6edLqFO5ViB7NZFc/+OZvujrafh8nOVpZRxQG7A4l31AWhdqF1Qfim4RgB","text":"I need to calculate 17 * 23. Let me do this step by step using the standard multiplication method.\n\n17 * 23\n\nI can break this down using the distributive property:\n17 * 23 = 17 * (20 + 3) = 17 * 20 + 17 * 3\n\nLet me calculate each part:\n17 * 20 = 17 * 2 * 10 = 34 * 10 = 340\n17 * 3 = 51\n\nSo 17 * 23 = 340 + 51 = 391\n\nLet me double-check this with the standard algorithm:\n 17\n × 23\n ----\n 51 (17 × 3)\n 340 (17 × 20)\n ----\n 391\n\nYes, that's correct."}}},{"text":"I'll solve 17 × 23 step by step using the distributive property method.\n\n**Step 1: Break down 23 into easier numbers**\n23 = 20 + 3\n\n**Step 2: Apply the distributive property**\n17 × 23 = 17 × (20 + 3) = (17 × 20) + (17 × 3)\n\n**Step 3: Calculate each part separately**\n- 17 × 20 = 340\n- 17 × 3 = 51\n\n**Step 4: Add the results together**\n340 + 51 = 391\n\n**Verification using standard multiplication:**\n```\n 17\n× 23\n-----\n 51 (17 × 3)\n 340 (17 × 20)\n-----\n 391\n```\n\nTherefore, **17 × 23 = 391**"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":55,"outputTokens":424,"serverToolUsage":{},"totalTokens":479}}435 5894 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.deepseek.r1-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 156 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":4096},"messages":[{"content":[{"text":"Think step by step: What is 17 * 23? Show your reasoning process."}],"role":"user"}]}HTTP/2.0 200 OK +Content-Length: 5728 +Content-Type: application/json +Date: Tue, 03 Mar 2026 19:45:39 GMT +X-Amzn-Requestid: 431da6fb-c37a-4f0b-96dd-a352070b11a5 + +{"metrics":{"latencyMs":10162},"output":{"message":{"content":[{"text":"\n\nTo calculate \\(17 \\times 23\\), we can use the **distributive property** and break down the multiplication into simpler steps:\n\n1. **Decompose 23 into 20 + 3**:\n \\[\n 17 \\times 23 = 17 \\times (20 + 3)\n \\]\n\n2. **Apply the distributive property**:\n \\[\n 17 \\times 20 + 17 \\times 3\n \\]\n\n3. **Calculate each part**:\n - \\(17 \\times 20 = 340\\)\n - \\(17 \\times 3 = 51\\)\n\n4. **Add the results**:\n \\[\n 340 + 51 = 391\n \\]\n\n**Verification using the difference of squares** (since \\(17 = 20 - 3\\) and \\(23 = 20 + 3\\)):\n\\[\n(20 - 3)(20 + 3) = 20^2 - 3^2 = 400 - 9 = 391\n\\]\n\n**Final Answer**: \n\\(\\boxed{391}\\)"},{"reasoningContent":{"reasoningText":{"text":"Okay, so I need to figure out what 17 multiplied by 23 is. Hmm, let me think. I remember that multiplication is just repeated addition, so maybe I can add 17 to itself 23 times, but that seems like it would take too long. There must be a better way.\n\nWait, maybe I can break down the numbers into smaller parts that are easier to multiply. Like, using the distributive property. Let me recall: a*(b + c) = a*b + a*c. So if I can split one of the numbers into tens and ones, that might help. Let's try splitting 23 into 20 and 3. That makes sense because 20 is a multiple of 10, which is easier to work with.\n\nSo, 17 * 23 becomes 17*(20 + 3). Applying the distributive property, that would be 17*20 + 17*3. Let me calculate each part separately.\n\nFirst, 17*20. Well, 17*2 is 34, so 17*20 must be 34*10, which is 340. Got that part down.\n\nNext, 17*3. Let me do that. 17*3... 10*3 is 30, and 7*3 is 21, so adding those together gives 30 + 21 = 51. So 17*3 is 51.\n\nNow, add the two results together: 340 + 51. Let's see, 340 + 50 is 390, and then add the remaining 1 to get 391. So, 17*23 should be 391. Wait, let me check that again to make sure I didn't make a mistake.\n\nAlternatively, maybe I can use another method to verify. Let's try the standard algorithm for multiplication. Multiply 17 by 23. So, writing it out vertically:\n\n 17\nx 23\n-------\n\nFirst, multiply 17 by 3 (the ones place of 23). 7*3 is 21, write down 1 and carry over 2. Then 1*3 is 3, plus the carried 2 makes 5. So that gives 51.\n\nNext, multiply 17 by 20 (the tens place of 23, which is 2*10). So 17*2 is 34, and since it's actually 20, we add a zero at the end, making it 340.\n\nNow, add 51 and 340 together. 51 + 340. Let's add the hundreds, tens, and ones. 300 + 0 = 300, 40 + 50 = 90, and 0 + 1 = 1. So 300 + 90 is 390, plus 1 is 391. Yep, same result.\n\nWait, just to be absolutely sure, maybe I can check using another method. Let's try the lattice method or maybe another decomposition. Let me try splitting both numbers. 17 is 10 + 7, and 23 is 20 + 3. Then using the distributive property again:\n\n(10 + 7)*(20 + 3) = 10*20 + 10*3 + 7*20 + 7*3.\n\nCalculating each term:\n\n10*20 = 200\n\n10*3 = 30\n\n7*20 = 140\n\n7*3 = 21\n\nNow add them all up: 200 + 30 is 230, 140 + 21 is 161. Then 230 + 161. Let's see, 200 + 100 = 300, 30 + 60 = 90, 0 + 1 = 1. So 300 + 90 is 390, plus 1 is 391. Same answer again. Okay, that seems consistent.\n\nAlternatively, maybe I can use estimation to check if 391 is a reasonable result. 17 is close to 15, and 23 is close to 25. 15*25 is 375. But since 17 is a bit more than 15 and 23 is a bit less than 25, the actual product should be a little higher than 375. 391 is 16 more than 375, which seems reasonable. If I had estimated 20*20=400, which is 17*23, 391 is just 9 less than 400, which also makes sense because both numbers are a bit less than 20 and 25. So the estimation checks out.\n\nAnother way to verify could be using subtraction. For example, 23 is 20 + 3, but maybe 23 is 25 - 2. Let's try that. 17*25 is easier. 25 is a quarter of 100, so 17*25 = (17*100)/4 = 1700/4 = 425. Then subtract 17*2 = 34. So 425 - 34 = 391. Yep, same answer. That works too.\n\nWait, let me try another angle. Maybe using base 10 or some other numerical tricks. For instance, 17*23. If I know that (a + b)(a - b) = a² - b², but that's for conjugate pairs. Here, 17 and 23 aren't symmetric around a common number. Let's see, the average of 17 and 23 is (17+23)/2 = 20. So 17 is 20 - 3, and 23 is 20 + 3. So actually, they are symmetric around 20. So then, (20 - 3)(20 + 3) = 20² - 3² = 400 - 9 = 391. Oh! That's a neat way to do it. So that's another method giving the same result. That's cool. So using the difference of squares formula here. That's smart because 17 and 23 are equally distant from 20. So that's a quicker way if you recognize that pattern.\n\nSo all these different methods—distributive property, standard algorithm, lattice method, difference of squares—all lead to the same answer: 391. That gives me confidence that the result is correct. I don't think I made any calculation errors along the way, especially since multiple methods confirm the same result. Let me just do a quick check with a calculator... Well, since I don't have a calculator here, but if I do 17*20=340 and 17*3=51, adding them gives 340+51=391. Yep, that's straightforward. So I think that's solid.\n\nAnother check: 23*17. Let's reverse the multiplication. 23*10=230, 23*7=161. 230+161=391. Same result. Multiplication is commutative, so it should be the same. Yep, that works too.\n\nAlright, I think I've thoroughly confirmed that 17 multiplied by 23 equals 391. All the different approaches and checks lead to the same answer, so I'm pretty sure that's correct.\n"}}}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":23,"outputTokens":1725,"serverToolUsage":{},"totalTokens":1748}}523 1660 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/openai.gpt-oss-120b-1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr Content-Length: 240 @@ -78,9 +106,37 @@ Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json {"additionalModelRequestFields":{"thinking":{"type":"enabled","budget_tokens":1024}},"inferenceConfig":{"maxTokens":4096},"messages":[{"content":[{"text":"Think step by step: What is 17 * 23? Show your reasoning process."}],"role":"user"}]}HTTP/2.0 200 OK -Content-Length: 1461 +Content-Length: 1494 Content-Type: application/json -Date: Fri, 23 Jan 2026 14:02:44 GMT -X-Amzn-Requestid: fc77b234-167f-4ccd-9c9a-f320f90c2cfb +Date: Tue, 03 Mar 2026 19:45:51 GMT +X-Amzn-Requestid: 6cf557c2-fe7a-4567-958c-474fc4e0c404 -{"metrics":{"latencyMs":4945},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"signature":"ErcBCkgICxABGAIiQP9Bulu/G73oh1GxqJxQ9Ks1m6cbHI16BEzf3FIH8xByln/FCWTrzgYxUw6Ll3pWT1F34Y6vR1s9mRR8zwmWpAISDLwa/EjhFM01LgKo5RoMRC/a3Vuff54ub2a6IjC2SquDWskU+1HJEXD6dyXnDppaMvJAiDFzJm9Uh26XoqqE3L3fVj8RMMq9FEKSx0MqHSdh10UVXiWPQ7L67aoq2v0UQvuhOJ4n0zgE8ZSOGAI=","text":"To calculate 17 * 23, I'll break it down into steps.\n\nFirst, let me multiply 17 by 20:\n17 * 20 = 17 * 2 * 10 = 34 * 10 = 340\n\nNext, let me multiply 17 by 3:\n17 * 3 = 51\n\nFinally, I'll add these results:\n17 * 23 = 17 * 20 + 17 * 3 = 340 + 51 = 391\n\nSo 17 * 23 = 391."}}},{"text":"# Calculating 17 × 23\n\nI'll solve this step by step:\n\n## Method 1: Direct multiplication\nI can multiply these numbers using the standard algorithm:\n```\n 17\n × 23\n-----\n 51 (17 × 3)\n 340 (17 × 20)\n-----\n 391\n```\n\n## Method 2: Breaking it down\nI can also break it down into parts:\n- 17 × 20 = 340\n- 17 × 3 = 51\n- Add the parts: 340 + 51 = 391\n\n## Method 3: Distributive property\nAnother way to think about it:\n- 17 × 23 = 17 × (20 + 3)\n- = (17 × 20) + (17 × 3)\n- = 340 + 51\n- = 391\n\nTherefore, 17 × 23 = 391."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":54,"outputTokens":373,"serverToolUsage":{},"totalTokens":427}} \ No newline at end of file +{"metrics":{"latencyMs":1447},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"text":"The user asks to think step by step: \"What is 17 * 23? Show your reasoning process.\" So answer with multiplication step by step. Provide reasoning: break down 17*23 = 17*(20+3) = 17*20 + 17*3 = 340 + 51 = 391. Or use other method. Provide final answer 391. Provide explanation."}}},{"text":"Sure! Let’s multiply 17 by 23 step‑by‑step.\n\n### 1️⃣ Write the problem in a way that makes it easy to use the distributive property \n\\(17 \\times 23\\) can be broken into two simpler pieces by splitting one of the numbers:\n\n\\[\n23 = 20 + 3\n\\]\n\nSo:\n\n\\[\n17 \\times 23 = 17 \\times (20 + 3)\n\\]\n\n### 2️⃣ Apply the distributive property (multiply each part separately) \n\n\\[\n17 \\times (20 + 3) = (17 \\times 20) + (17 \\times 3)\n\\]\n\n### 3️⃣ Compute each of those two products \n\n- **\\(17 \\times 20\\):** \n Multiply 17 by 2 first → \\(17 \\times 2 = 34\\). \n Then add a zero because we’re really multiplying by 20 (i.e., \\(2 \\times 10\\)). \n So \\(17 \\times 20 = 340\\).\n\n- **\\(17 \\times 3\\):** \n \\(17 \\times 3 = 51\\).\n\n### 4️⃣ Add the two results together \n\n\\[\n340 + 51 = 391\n\\]\n\n### ✅ Final answer \n\n\\[\n\\boxed{391}\n\\]\n\nSo, 17 multiplied by 23 equals **391**."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":83,"outputTokens":386,"serverToolUsage":{},"totalTokens":469}}522 2034 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/openai.gpt-oss-20b-1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 240 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"additionalModelRequestFields":{"thinking":{"type":"enabled","budget_tokens":1024}},"inferenceConfig":{"maxTokens":4096},"messages":[{"content":[{"text":"Think step by step: What is 17 * 23? Show your reasoning process."}],"role":"user"}]}HTTP/2.0 200 OK +Content-Length: 1868 +Content-Type: application/json +Date: Tue, 03 Mar 2026 19:46:04 GMT +X-Amzn-Requestid: 09db0006-430e-40f1-ab43-4cadddc636f2 + +{"metrics":{"latencyMs":1482},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"text":"We need to compute 17 * 23. We should show step-by-step reasoning. Probably show multiplication process: 17 * 23 = 17 * (20 + 3) = 17*20 + 17*3 = 340 + 51 = 391. Or show long multiplication: 23 * 17. Let's produce a clear reasoning. Also show using distributive law and patterns. This is straightforward."}}},{"text":"**Step 1 – Recognize the numbers**\n\nWe need to multiply\n\n\\[\n17 \\times 23\n\\]\n\nBoth numbers are small enough to handle by hand or by mental arithmetic, so we can use the distributive property of multiplication over addition.\n\n---\n\n**Step 2 – Decompose one of the factors**\n\nChoose to split the number 23 into a sum that’s easier to work with:\n\n\\[\n23 = 20 + 3\n\\]\n\n---\n\n**Step 3 – Apply the distributive law**\n\n\\[\n17 \\times 23 = 17 \\times (20 + 3)\n\\]\n\nBy the distributive property, this equals\n\n\\[\n17 \\times 20 + 17 \\times 3\n\\]\n\n---\n\n**Step 4 – Compute the two simpler products**\n\n1. **\\(17 \\times 20\\)** \n Multiplying by 20 is the same as multiplying by 2 and then adding a zero (i.e., adding a factor of 10). \n \\[\n 17 \\times 2 = 34 \\quad\\Longrightarrow\\quad 34 \\times 10 = 340\n \\]\n\n2. **\\(17 \\times 3\\)** \n \\[\n 17 \\times 3 = 51\n \\]\n\n---\n\n**Step 5 – Add the results**\n\n\\[\n340 + 51 = 391\n\\]\n\n---\n\n**Result**\n\n\\[\n\\boxed{17 \\times 23 = 391}\n\\]\n\n---\n\n**Optional check (long multiplication)**\n\n```\n 17\n × 23\n -------\n 51 (17 × 3)\n+ 340 (17 × 20, shift one place left)\n -------\n 391\n```\n\nBoth methods confirm that 17 multiplied by 23 equals 391."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":83,"outputTokens":480,"serverToolUsage":{},"totalTokens":563}}523 3649 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/moonshot.kimi-k2-thinking/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 240 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"additionalModelRequestFields":{"thinking":{"type":"enabled","budget_tokens":1024}},"inferenceConfig":{"maxTokens":4096},"messages":[{"content":[{"text":"Think step by step: What is 17 * 23? Show your reasoning process."}],"role":"user"}]}HTTP/2.0 200 OK +Content-Length: 3483 +Content-Type: application/json +Date: Tue, 03 Mar 2026 19:46:23 GMT +X-Amzn-Requestid: fe153ed6-94b3-40fa-a829-8667594ed2ae + +{"metrics":{"latencyMs":8245},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"text":" We need to calculate the product of 17 and 23. Then we also need to show the step-by-step reasoning process. Let me think about this.\n\nWe could do direct multiplication, but perhaps we can use a mental math strategy. The numbers are close to 20, so we could use the difference of squares technique or the \"multiply near a base\" technique.\n\nLet me try the difference of squares approach: 17 * 23 = (20 - 3) * (20 + 3) = 20² - 3² = 400 - 9 = 391.\n\nThat's interesting! The product is 391.\n\nBut let me also do it the traditional way: 17 * 23 = 17 * (20 + 3) = 17 * 20 + 17 * 3 = 340 + 51 = 391.\n\nOr: 23 * 17 = 23 * (10 + 7) = 230 + 161 = 391.\n\nEach method gives the same result: 391.\n\nNow, let me think about how to show the reasoning process step-by-step in a clear way. I should explain the method, break it down, and then arrive at the answer. The difference of squares method is elegant and efficient, but I could also show the standard multiplication method.\n\nSince the question asks me to \"think step by step\", I should:\n1. Identify what we're calculating (17 * 23)\n2. Choose a method (I'll go with difference of squares as it's elegant, but also mention the standard method)\n3. Show the steps\n4. Arrive at the final answer\n\nLet me structure my response to be as clear as possible.\n\nActually, let me double-check my calculation:\n17 * 23 = ?\n17 * 20 = 340\n17 * 3 = 51\n340 + 51 = 391\n\nYes, that's correct.\n\nFor the difference of squares method:\n(20 - 3) * (20 + 3) = 20² - 3² = 400 - 9 = 391\n\nThis is correct too.\n\nThe standard long multiplication:\n 17\n × 23\n ----\n 51 (17 × 3)\n 340 (17 × 20, shifted)\n ----\n 391\n\nAll methods confirm the answer is 391.\n\nNow, for the step-by-step reasoning process, I'll focus on one clear method and explain each step. The difference of squares method is particularly nice for this problem because the numbers are symmetric around 20, making the calculation very straightforward. Let me write out the reasoning:\n\nStep 1: Recognize that 17 and 23 are equidistant from 20 (they differ by ±3).\nStep 2: Use the algebraic identity (a - b)(a + b) = a² - b²\nStep 3: Set a = 20 and b = 3\nStep 4: Calculate a² = 400 and b² = 9\nStep 5: Subtract: 400 - 9 = 391\n\nThis is clean and elegant. I'll present this as the main method but also mention as an alternative the standard decomposition method to show understanding of multiple approaches."}}},{"text":" **Step 1:** Identify the multiplication problem and look for an efficient approach.\nI need to calculate 17 × 23. I notice these numbers are symmetric around 20 (17 is 3 less than 20, and 23 is 3 more than 20).\n\n**Step 2:** Use the difference of squares formula.\nI can rewrite the product as: (20 - 3) × (20 + 3)\n\n**Step 3:** Apply the algebraic identity (a - b)(a + b) = a² - b².\nHere, a = 20 and b = 3, so:\n(20 - 3) × (20 + 3) = 20² - 3²\n\n**Step 4:** Calculate each term.\n20² = 400\n3² = 9\n\n**Step 5:** Subtract to find the final answer.\n400 - 9 = **391**\n\n---\n\n**Alternative check:**\nI can also verify using the distributive property:\n17 × 23 = 17 × (20 + 3) = (17 × 20) + (17 × 3) = 340 + 51 = **391**\n\nBoth methods confirm the answer is **391**."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":46,"outputTokens":920,"serverToolUsage":{},"totalTokens":966}} \ No newline at end of file diff --git a/llms/bedrock/testdata/TestAmazonReasoningStreamingConverseAPI.httprr b/llms/bedrock/testdata/TestAmazonReasoningStreamingConverseAPI.httprr index 8dc449e2c15adf6ce612a278dfdaf3271ebf91d4..648130d0c5d48bd80d4406590144c1c882c20ec0 100644 GIT binary patch literal 188456 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 U00R=NwC3}>P|aTT>Qy)X7f3r!a{vGU literal 139502 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 Bo&o>> diff --git a/llms/bedrock/testdata/TestAmazonSequentialToolCallsWithThinkingConverseAPI.httprr b/llms/bedrock/testdata/TestAmazonSequentialToolCallsWithThinkingConverseAPI.httprr new file mode 100644 index 00000000..1f04064d --- /dev/null +++ b/llms/bedrock/testdata/TestAmazonSequentialToolCallsWithThinkingConverseAPI.httprr @@ -0,0 +1,30 @@ +httprr trace v1 +770 1360 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 466 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"additionalModelRequestFields":{"thinking":{"type":"enabled","budget_tokens":2048}},"inferenceConfig":{"maxTokens":4096,"temperature":1},"messages":[{"content":[{"text":"Calculate (5 + 3) and then multiply by 2"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"Perform a calculation","inputSchema":{"json":{"properties":{"expression":{"type":"string"}},"required":["expression"],"type":"object"}},"name":"calculate"}}]}}HTTP/2.0 200 OK +Content-Length: 1194 +Content-Type: application/json +Date: Tue, 03 Mar 2026 21:48:15 GMT +X-Amzn-Requestid: ed53c3b5-af84-49b0-8450-c098606f9f2c + +{"metrics":{"latencyMs":3157},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"signature":"EuwCCkgICxABGAIqQBilFNe+5INhzkPazuSJTvJrubMx4pRE+Kb+2kD8s7gmSWWCmwLrmUxONoNlznIFuPDOEEi36mUHJsCm7ryozN0SDHw0pifl33kdexDNthoMDbrknXWBmNZeeRaNIjByT1UDoC8V/+szUCDpTO3fDBxAlQ1O9ZsmAIXda37nDHr229HG6/+6ir3AfsHqBMMq0QHfFC56b+GIVI71pK5Q716xUZ0wE/MYSZO39XHTr9FoYXJqxBC2GMRkBpzYXLAVNs3T6QMMB4YhEHmWM8DDAqBwfiPFGgOEjXRv2Byxs3PTH7vzW3Znp0cqp59Uy4v5os9bkF9dA3lb0k6JFXkv9K2m/n52dc0gF8djsCczVzdhSyq7QnaG9frkphhgs29K4PI2efhIYoT6YYxQacD/0beCzMoq7VwH2ffPDOWdVP87e64lwejUoIU6K2lS48r8ArruZ5BKuqeCEukvHo3FFKy/JBgB","text":"The user wants me to:\n1. Calculate (5 + 3)\n2. Then multiply the result by 2\n\nThis is essentially calculating (5 + 3) * 2, which equals 8 * 2 = 16.\n\nI can do this in one calculation: (5 + 3) * 2"}}},{"toolUse":{"input":{"expression":"(5 + 3) * 2"},"name":"calculate","toolUseId":"tooluse_cQy4nWyTZ0YD6iFmxNOHiX","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":597,"outputTokens":143,"serverToolUsage":{},"totalTokens":740}}1824 563 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 1519 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"additionalModelRequestFields":{"thinking":{"type":"enabled","budget_tokens":2048}},"inferenceConfig":{"maxTokens":4096,"temperature":1},"messages":[{"content":[{"text":"Calculate (5 + 3) and then multiply by 2"}],"role":"user"},{"content":[{"reasoningContent":{"reasoningText":{"signature":"EuwCCkgICxABGAIqQBilFNe+5INhzkPazuSJTvJrubMx4pRE+Kb+2kD8s7gmSWWCmwLrmUxONoNlznIFuPDOEEi36mUHJsCm7ryozN0SDHw0pifl33kdexDNthoMDbrknXWBmNZeeRaNIjByT1UDoC8V/+szUCDpTO3fDBxAlQ1O9ZsmAIXda37nDHr229HG6/+6ir3AfsHqBMMq0QHfFC56b+GIVI71pK5Q716xUZ0wE/MYSZO39XHTr9FoYXJqxBC2GMRkBpzYXLAVNs3T6QMMB4YhEHmWM8DDAqBwfiPFGgOEjXRv2Byxs3PTH7vzW3Znp0cqp59Uy4v5os9bkF9dA3lb0k6JFXkv9K2m/n52dc0gF8djsCczVzdhSyq7QnaG9frkphhgs29K4PI2efhIYoT6YYxQacD/0beCzMoq7VwH2ffPDOWdVP87e64lwejUoIU6K2lS48r8ArruZ5BKuqeCEukvHo3FFKy/JBgB","text":"The user wants me to:\n1. Calculate (5 + 3)\n2. Then multiply the result by 2\n\nThis is essentially calculating (5 + 3) * 2, which equals 8 * 2 = 16.\n\nI can do this in one calculation: (5 + 3) * 2"}}}],"role":"assistant"},{"content":[{"toolUse":{"input":{"expression":"(5 + 3) * 2"},"name":"calculate","toolUseId":"tooluse_cQy4nWyTZ0YD6iFmxNOHiX"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"8"}],"toolUseId":"tooluse_cQy4nWyTZ0YD6iFmxNOHiX"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"Perform a calculation","inputSchema":{"json":{"properties":{"expression":{"type":"string"}},"required":["expression"],"type":"object"}},"name":"calculate"}}]}}HTTP/2.0 200 OK +Content-Length: 398 +Content-Type: application/json +Date: Tue, 03 Mar 2026 21:48:18 GMT +X-Amzn-Requestid: c1c05ece-0643-4d0f-8d45-0890a2a92ff7 + +{"metrics":{"latencyMs":2419},"output":{"message":{"content":[{"text":"The result is **16**.\n\nTo break it down:\n- First: 5 + 3 = 8\n- Then: 8 × 2 = 16"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":753,"outputTokens":43,"serverToolUsage":{},"totalTokens":796}} \ No newline at end of file diff --git a/llms/bedrock/testdata/TestAmazonSingleToolCallWithThinkingConverseAPI.httprr b/llms/bedrock/testdata/TestAmazonSingleToolCallWithThinkingConverseAPI.httprr new file mode 100644 index 00000000..b0497784 --- /dev/null +++ b/llms/bedrock/testdata/TestAmazonSingleToolCallWithThinkingConverseAPI.httprr @@ -0,0 +1,30 @@ +httprr trace v1 +762 1364 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 458 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"additionalModelRequestFields":{"thinking":{"type":"enabled","budget_tokens":2048}},"inferenceConfig":{"maxTokens":4096,"temperature":1},"messages":[{"content":[{"text":"What's the weather in Boston?"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"Get weather for a location","inputSchema":{"json":{"properties":{"location":{"type":"string"}},"required":["location"],"type":"object"}},"name":"get_weather"}}]}}HTTP/2.0 200 OK +Content-Length: 1198 +Content-Type: application/json +Date: Tue, 03 Mar 2026 21:48:02 GMT +X-Amzn-Requestid: eda4eb6d-a4af-4275-b548-60a790f200d4 + +{"metrics":{"latencyMs":3751},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"signature":"EvECCkgICxABGAIqQHhi2RPLJVjY2ondbMYFTjaGTKxCARpJBG6uf3ji0k5e0cCnNZsYHOUjFE4no1zIbIza9RDZ81JxzjgZKmf03dcSDFFVMZKstk3+/dXaRxoMUoFtAD/c3JZYz4XuIjBp2+D/mjtlTobiLTLiMCj8NKtEC5nV3eX3Dz3KTifdDhPwp5cr+T42rE42WDPoxQkq1gH+A52CkJZYI3e1aP1/K8j8Bhs3wgCY6kj1/bpRWQbjvNwEBnc9Emvg67ioG0MVMwi9aOG3F7fz+m+TDAePJMTRHjN3+u4JLJE6CBE/fB440f62Yi/17qLhEGwtSdJRaV4lLWKfRAMh+McoAVpIbT0raBOAbPTBaBmvvkMBom57iLhjoqHA80eJoCfsqgZF6ZYCg4YGiXqHz1K/uFtcUG+90icfZcGgp+qFsual0NvAVwOx8AVDQOkznLXgDbfRXx5DWSRNrDhvKPhaUFsXV3+GskhsMW/kGAE=","text":"The user is asking for the weather in Boston. I have access to a get_weather function that takes a location parameter. I have all the information I need to make this call - the location is \"Boston\"."}}},{"toolUse":{"input":{"location":"Boston"},"name":"get_weather","toolUseId":"tooluse_xSOkEzYy3oYAwEkWhnnZOG","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":593,"outputTokens":104,"serverToolUsage":{},"totalTokens":697}}1866 549 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 1561 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"additionalModelRequestFields":{"thinking":{"type":"enabled","budget_tokens":2048}},"inferenceConfig":{"maxTokens":4096,"temperature":1},"messages":[{"content":[{"text":"What's the weather in Boston?"}],"role":"user"},{"content":[{"reasoningContent":{"reasoningText":{"signature":"EvECCkgICxABGAIqQHhi2RPLJVjY2ondbMYFTjaGTKxCARpJBG6uf3ji0k5e0cCnNZsYHOUjFE4no1zIbIza9RDZ81JxzjgZKmf03dcSDFFVMZKstk3+/dXaRxoMUoFtAD/c3JZYz4XuIjBp2+D/mjtlTobiLTLiMCj8NKtEC5nV3eX3Dz3KTifdDhPwp5cr+T42rE42WDPoxQkq1gH+A52CkJZYI3e1aP1/K8j8Bhs3wgCY6kj1/bpRWQbjvNwEBnc9Emvg67ioG0MVMwi9aOG3F7fz+m+TDAePJMTRHjN3+u4JLJE6CBE/fB440f62Yi/17qLhEGwtSdJRaV4lLWKfRAMh+McoAVpIbT0raBOAbPTBaBmvvkMBom57iLhjoqHA80eJoCfsqgZF6ZYCg4YGiXqHz1K/uFtcUG+90icfZcGgp+qFsual0NvAVwOx8AVDQOkznLXgDbfRXx5DWSRNrDhvKPhaUFsXV3+GskhsMW/kGAE=","text":"The user is asking for the weather in Boston. I have access to a get_weather function that takes a location parameter. I have all the information I need to make this call - the location is \"Boston\"."}}}],"role":"assistant"},{"content":[{"toolUse":{"input":{"location":"Boston"},"name":"get_weather","toolUseId":"tooluse_xSOkEzYy3oYAwEkWhnnZOG"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"{\"temperature\": 72, \"condition\": \"sunny\"}"}],"toolUseId":"tooluse_xSOkEzYy3oYAwEkWhnnZOG"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"Get weather for a location","inputSchema":{"json":{"properties":{"location":{"type":"string"}},"required":["location"],"type":"object"}},"name":"get_weather"}}]}}HTTP/2.0 200 OK +Content-Length: 384 +Content-Type: application/json +Date: Tue, 03 Mar 2026 21:48:05 GMT +X-Amzn-Requestid: 4fcac4ac-e91a-4213-a363-4ece03e794d7 + +{"metrics":{"latencyMs":2319},"output":{"message":{"content":[{"text":"The weather in Boston is currently sunny with a temperature of 72°F."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":721,"outputTokens":19,"serverToolUsage":{},"totalTokens":740}} \ No newline at end of file diff --git a/llms/bedrock/testdata/TestAmazonStreamingOutputConverseAPI.httprr b/llms/bedrock/testdata/TestAmazonStreamingOutputConverseAPI.httprr index 624d56fd9ab2b97d892584df37c3df0247cd0ec0..2c4c8e726a00ba51ccb42effedd859a702828e0e 100644 GIT binary patch literal 416149 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

bI9rOjL>BvV7%|&?z{q;+)UcM-0_m%;Qh$K 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 user wants to multiply 15 by 8. The calculator tool can handle this as it supports multiplication operations. I'll use the calculator with the provided numbers.\n\n"},{"toolUse":{"input":{"a":15,"b":8,"operation":"multiply"},"name":"calculator","toolUseId":"tooluse_qpz9K2ctQq6lXj7mWJr31Q"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":777,"outputTokens":66,"serverToolUsage":{},"totalTokens":843}}1101 1011 +{"metrics":{"latencyMs":4485},"output":{"message":{"content":[{"text":"The user's request is to calculate 15 multiplied by 8. Since multiplication is one of the basic arithmetic operations supported by the calculator tool, I can proceed directly. First, I'll verify that both numbers are integers and the operation is valid. The calculator requires parameters: operation (string), a (number), and b (number). Here, operation=\"multiply\", a=15, and b=8 all meet the required data types. No other tools are needed as this is a straightforward multiplication problem.\n\n"},{"toolUse":{"input":{"a":15,"b":8,"operation":"multiply"},"name":"calculator","toolUseId":"tooluse_GAVVsg1gytFgCDl6AnVVwL"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":777,"outputTokens":137,"serverToolUsage":{},"totalTokens":914}}1140 768 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.amazon.nova-premier-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr -Content-Length: 814 +Content-Length: 853 Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json -{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{},"name":"calculator","toolUseId":"tooluse_qpz9K2ctQq6lXj7mWJr31Q"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_qpz9K2ctQq6lXj7mWJr31Q"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK -Content-Length: 846 +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_GAVVsg1gytFgCDl6AnVVwL"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_GAVVsg1gytFgCDl6AnVVwL"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 603 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:39:19 GMT -X-Amzn-Requestid: 029814d6-ee12-4c57-926f-6f6a57ad1763 +Date: Tue, 03 Mar 2026 16:58:36 GMT +X-Amzn-Requestid: 1001a07e-ccb3-40e7-a86e-2a4db5f6b30b -{"metrics":{"latencyMs":6634},"output":{"message":{"content":[{"text":"The calculator tool was used to multiply 15 by 8. The operation performed was a multiplication, which is one of the basic arithmetic operations supported by the tool. The parameters provided were operation=\"multiply\", a=15, and b=8. These values are valid according to the tool's requirements, as both a and b are numbers and the operation is in the allowed enum list. The result obtained from the tool was 120, which is the correct product of 15 and 8. Since the calculation was straightforward and the tool provided the expected result, no further tools or steps are needed. The result of 15 multiplied by 8 is 120."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":820,"outputTokens":148,"serverToolUsage":{},"totalTokens":968}}857 628 +{"metrics":{"latencyMs":2872},"output":{"message":{"content":[{"text":"The multiplication of 15 and 8 has been calculated using the tool, resulting in 120. This is a straightforward arithmetic operation where each digit of the second number is multiplied by the first number, then the results are summed, taking into account the positional value. The tool has provided the correct result for this operation. The result of 15 multiplied by 8 is 120."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":832,"outputTokens":88,"serverToolUsage":{},"totalTokens":920}}857 681 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.amazon.nova-pro-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -64,26 +64,26 @@ Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK -Content-Length: 463 +Content-Length: 516 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:39:21 GMT -X-Amzn-Requestid: 845a59e2-fd6d-41bd-be4d-a5d8e14efe41 +Date: Tue, 03 Mar 2026 16:58:43 GMT +X-Amzn-Requestid: a2c18054-d33c-486a-b9aa-1fb44c95dbc9 -{"metrics":{"latencyMs":1033},"output":{"message":{"content":[{"text":" The user has requested a multiplication operation. I will use the calculator tool to perform this operation. \n"},{"toolUse":{"input":{"a":15,"b":8,"operation":"multiply"},"name":"calculator","toolUseId":"tooluse_gnH1Q_N9RCaV52Z9jCo8pA"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":462,"outputTokens":50,"serverToolUsage":{},"totalTokens":512}}1097 397 +{"metrics":{"latencyMs":1188},"output":{"message":{"content":[{"text":" To solve the multiplication of 15 and 8, I will use the calculator tool with the operation set to 'multiply', the first number as 15, and the second number as 8. \n"},{"toolUse":{"input":{"a":15,"b":8,"operation":"multiply"},"name":"calculator","toolUseId":"tooluse_8QAF4wuKQA0tA30UguZVEU"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":462,"outputTokens":74,"serverToolUsage":{},"totalTokens":536}}1136 398 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.amazon.nova-pro-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr -Content-Length: 814 +Content-Length: 853 Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json -{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{},"name":"calculator","toolUseId":"tooluse_gnH1Q_N9RCaV52Z9jCo8pA"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_gnH1Q_N9RCaV52Z9jCo8pA"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK -Content-Length: 232 +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_8QAF4wuKQA0tA30UguZVEU"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_8QAF4wuKQA0tA30UguZVEU"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 233 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:39:23 GMT -X-Amzn-Requestid: 1a2cc193-40fa-492d-87f1-be9f5f8cf78d +Date: Tue, 03 Mar 2026 16:59:01 GMT +X-Amzn-Requestid: fa6cb90c-2eca-41fe-b315-ee4c0509cc69 -{"metrics":{"latencyMs":554},"output":{"message":{"content":[{"text":"The result of 15 * 8 is 120."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":503,"outputTokens":15,"serverToolUsage":{},"totalTokens":518}}858 626 +{"metrics":{"latencyMs":1258},"output":{"message":{"content":[{"text":"The result of 15 * 8 is 120."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":515,"outputTokens":15,"serverToolUsage":{},"totalTokens":530}}858 679 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.amazon.nova-lite-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -92,26 +92,26 @@ Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK -Content-Length: 461 +Content-Length: 514 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:39:24 GMT -X-Amzn-Requestid: af1f80d1-05ac-4c64-ad6f-1158fbf8c224 +Date: Tue, 03 Mar 2026 16:59:08 GMT +X-Amzn-Requestid: ae093267-17b5-4e07-9b50-984c58832f21 -{"metrics":{"latencyMs":705},"output":{"message":{"content":[{"text":"The User's request is to calculate the product of 15 and 8. The tool 'calculator' can perform this operation.\n"},{"toolUse":{"input":{"a":15,"b":8,"operation":"multiply"},"name":"calculator","toolUseId":"tooluse_XRIMmY-YTMi9b08_V2j7mA"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":462,"outputTokens":59,"serverToolUsage":{},"totalTokens":521}}1098 527 +{"metrics":{"latencyMs":823},"output":{"message":{"content":[{"text":"The User wants to calculate the product of 15 and 8. The calculator tool can perform this operation. I will use the calculator tool with the 'multiply' operation.\n"},{"toolUse":{"input":{"a":15,"b":8,"operation":"multiply"},"name":"calculator","toolUseId":"tooluse_BwmUooY87MBMCcvyedVDKW"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":462,"outputTokens":66,"serverToolUsage":{},"totalTokens":528}}1137 524 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.amazon.nova-lite-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr -Content-Length: 814 +Content-Length: 853 Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json -{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{},"name":"calculator","toolUseId":"tooluse_XRIMmY-YTMi9b08_V2j7mA"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_XRIMmY-YTMi9b08_V2j7mA"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK -Content-Length: 362 +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_BwmUooY87MBMCcvyedVDKW"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_BwmUooY87MBMCcvyedVDKW"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 359 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:39:26 GMT -X-Amzn-Requestid: 54e5bba6-9728-4624-8102-cc0f01430f14 +Date: Tue, 03 Mar 2026 16:59:25 GMT +X-Amzn-Requestid: 86e8f56d-c1bf-4d6d-859e-b2384a68f46e -{"metrics":{"latencyMs":657},"output":{"message":{"content":[{"text":" I have the result from the calculator tool. The multiplication of 15 and 8 is 120. \n The result of 15 * 8 is 120. "}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":503,"outputTokens":51,"serverToolUsage":{},"totalTokens":554}}859 633 +{"metrics":{"latencyMs":703},"output":{"message":{"content":[{"text":" I have the result from the calculator tool, which shows that 15 * 8 equals 120. \n The result of 15 * 8 is 120. "}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":515,"outputTokens":51,"serverToolUsage":{},"totalTokens":566}}859 638 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.amazon.nova-micro-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -120,27 +120,27 @@ Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK -Content-Length: 468 +Content-Length: 473 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:39:28 GMT -X-Amzn-Requestid: 20b5fa05-2cc6-4803-9d0e-f21af2016d3e +Date: Tue, 03 Mar 2026 16:59:31 GMT +X-Amzn-Requestid: ab029dae-60ac-45ec-93ba-48c326ea0706 -{"metrics":{"latencyMs":516},"output":{"message":{"content":[{"text":" The User wants to calculate the product of 15 and 8. I can use the calculator tool to perform this multiplication. \n"},{"toolUse":{"input":{"a":15,"b":8,"operation":"multiply"},"name":"calculator","toolUseId":"tooluse_1BiuAtKKQvWnjNB1emhidg"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":462,"outputTokens":57,"serverToolUsage":{},"totalTokens":519}}1099 397 +{"metrics":{"latencyMs":535},"output":{"message":{"content":[{"text":" The user has requested a multiplication calculation of 15 * 8. I can use the calculator tool to perform this operation. \n"},{"toolUse":{"input":{"a":15,"b":8,"operation":"multiply"},"name":"calculator","toolUseId":"tooluse_1ACatNfn2I9OBzAmC3yKOF"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":462,"outputTokens":57,"serverToolUsage":{},"totalTokens":519}}1138 413 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.amazon.nova-micro-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr -Content-Length: 814 +Content-Length: 853 Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json -{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{},"name":"calculator","toolUseId":"tooluse_1BiuAtKKQvWnjNB1emhidg"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_1BiuAtKKQvWnjNB1emhidg"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK -Content-Length: 232 +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_1ACatNfn2I9OBzAmC3yKOF"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_1ACatNfn2I9OBzAmC3yKOF"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 248 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:39:29 GMT -X-Amzn-Requestid: fac42b2b-0c33-47fc-90fd-1e490d6b3a08 +Date: Tue, 03 Mar 2026 16:59:48 GMT +X-Amzn-Requestid: 788155f3-056d-4677-a9a4-1c80598fea3d -{"metrics":{"latencyMs":394},"output":{"message":{"content":[{"text":"The result of 15 * 8 is 120."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":503,"outputTokens":15,"serverToolUsage":{},"totalTokens":518}}876 611 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-5-20251101-v1%3A0/converse HTTP/1.1 +{"metrics":{"latencyMs":404},"output":{"message":{"content":[{"text":"The result of the calculation 15 * 8 is 120."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":515,"outputTokens":17,"serverToolUsage":{},"totalTokens":532}}863 611 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-6-v1/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr Content-Length: 574 @@ -150,25 +150,25 @@ Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK Content-Length: 446 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:39:33 GMT -X-Amzn-Requestid: c4cc4ec3-44b0-4e97-b98a-e683ebe8ffd7 +Date: Tue, 03 Mar 2026 16:59:56 GMT +X-Amzn-Requestid: e4521d57-97a7-423e-97a4-6a38f8a2933f -{"metrics":{"latencyMs":2123},"output":{"message":{"content":[{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_KnTDpjlWQniyhKdzmHeanw","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":628,"outputTokens":85,"serverToolUsage":{},"totalTokens":713}}1116 513 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-5-20251101-v1%3A0/converse HTTP/1.1 +{"metrics":{"latencyMs":2238},"output":{"message":{"content":[{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_TF8pVu8N2CuZZCKtj9PxGS","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":629,"outputTokens":86,"serverToolUsage":{},"totalTokens":715}}1142 517 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-6-v1/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr -Content-Length: 814 +Content-Length: 853 Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json -{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{},"name":"calculator","toolUseId":"tooluse_KnTDpjlWQniyhKdzmHeanw"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_KnTDpjlWQniyhKdzmHeanw"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK -Content-Length: 348 +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_TF8pVu8N2CuZZCKtj9PxGS"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_TF8pVu8N2CuZZCKtj9PxGS"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 352 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:39:37 GMT -X-Amzn-Requestid: 92f0d4b9-726d-441a-8538-a3bcb72775ad +Date: Tue, 03 Mar 2026 17:00:14 GMT +X-Amzn-Requestid: c938fad7-657a-47f6-ba88-c5f7815d5b56 -{"metrics":{"latencyMs":3074},"output":{"message":{"content":[{"text":"The result of 15 × 8 is **120**."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":676,"outputTokens":17,"serverToolUsage":{},"totalTokens":693}}877 610 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-haiku-4-5-20251001-v1%3A0/converse HTTP/1.1 +{"metrics":{"latencyMs":1795},"output":{"message":{"content":[{"text":"The result of **15 × 8** is **120**."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":728,"outputTokens":17,"serverToolUsage":{},"totalTokens":745}}862 665 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr Content-Length: 574 @@ -176,55 +176,170 @@ Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK -Content-Length: 445 +Content-Length: 500 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:39:39 GMT -X-Amzn-Requestid: a112c85c-aa78-4c48-8148-418c90be89d1 +Date: Tue, 03 Mar 2026 17:00:22 GMT +X-Amzn-Requestid: 1c30d501-93c0-4691-8d12-97b545808932 -{"metrics":{"latencyMs":940},"output":{"message":{"content":[{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_1WECBHlDTLCfHJcmb1uW4w","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":628,"outputTokens":86,"serverToolUsage":{},"totalTokens":714}}1117 495 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-haiku-4-5-20251001-v1%3A0/converse HTTP/1.1 +{"metrics":{"latencyMs":1502},"output":{"message":{"content":[{"text":"I'll calculate 15 * 8 for you right away!"},{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_gYGMT5G3aVmOxo2jhhqnuD","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":629,"outputTokens":101,"serverToolUsage":{},"totalTokens":730}}1141 512 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr -Content-Length: 814 +Content-Length: 853 Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json -{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{},"name":"calculator","toolUseId":"tooluse_1WECBHlDTLCfHJcmb1uW4w"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_1WECBHlDTLCfHJcmb1uW4w"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK -Content-Length: 330 -Content-Type: application/json -Date: Fri, 23 Jan 2026 13:39:41 GMT -X-Amzn-Requestid: 95acb377-c780-47d3-97b2-f89c2af0167a - -{"metrics":{"latencyMs":644},"output":{"message":{"content":[{"text":"15 * 8 = **120**"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":676,"outputTokens":13,"serverToolUsage":{},"totalTokens":689}}878 611 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse HTTP/1.1 -Host: bedrock-runtime.us-east-1.amazonaws.com -User-Agent: langchaingo-httprr -Content-Length: 574 -Authorization: AWS4-HMAC-SHA256 test-api-key -Content-Type: application/json - -{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK -Content-Length: 446 -Content-Type: application/json -Date: Fri, 23 Jan 2026 13:39:46 GMT -X-Amzn-Requestid: eaad1d1f-a6cc-4914-9ea2-e067ede9b6c4 - -{"metrics":{"latencyMs":3771},"output":{"message":{"content":[{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_ql8hDScwTcuWhAYxz2Eeuw","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":628,"outputTokens":85,"serverToolUsage":{},"totalTokens":713}}1118 512 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse HTTP/1.1 -Host: bedrock-runtime.us-east-1.amazonaws.com -User-Agent: langchaingo-httprr -Content-Length: 814 -Authorization: AWS4-HMAC-SHA256 test-api-key -Content-Type: application/json - -{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{},"name":"calculator","toolUseId":"tooluse_ql8hDScwTcuWhAYxz2Eeuw"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_ql8hDScwTcuWhAYxz2Eeuw"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_gYGMT5G3aVmOxo2jhhqnuD"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_gYGMT5G3aVmOxo2jhhqnuD"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK Content-Length: 347 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:39:49 GMT -X-Amzn-Requestid: a1727ccd-919d-4d51-8f0c-07fcc2358bd0 +Date: Tue, 03 Mar 2026 17:00:39 GMT +X-Amzn-Requestid: 3d8a87c5-8d14-40da-ad1d-63c7f5909b69 -{"metrics":{"latencyMs":1780},"output":{"message":{"content":[{"text":"The result of 15 * 8 is **120**."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":676,"outputTokens":17,"serverToolUsage":{},"totalTokens":693}}874 653 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-20250514-v1%3A0/converse HTTP/1.1 +{"metrics":{"latencyMs":1067},"output":{"message":{"content":[{"text":"The result of **15 × 8 = 120**."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":728,"outputTokens":17,"serverToolUsage":{},"totalTokens":745}}876 611 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-5-20251101-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 574 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 446 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:00:48 GMT +X-Amzn-Requestid: 9327ac6c-0cbb-4a21-8bcc-c173cdcbc841 + +{"metrics":{"latencyMs":2318},"output":{"message":{"content":[{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_g5vGsMeFhNl3t52qor3tn5","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":628,"outputTokens":85,"serverToolUsage":{},"totalTokens":713}}1155 497 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-5-20251101-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 853 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_g5vGsMeFhNl3t52qor3tn5"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_g5vGsMeFhNl3t52qor3tn5"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 332 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:01:06 GMT +X-Amzn-Requestid: 69a8b20f-cd83-4811-abcf-9d1758cc189b + +{"metrics":{"latencyMs":1846},"output":{"message":{"content":[{"text":"15 × 8 = **120**"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":727,"outputTokens":13,"serverToolUsage":{},"totalTokens":740}}877 611 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-haiku-4-5-20251001-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 574 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 446 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:01:13 GMT +X-Amzn-Requestid: 6fdfdd42-310d-470f-aeaa-e2056b7d6e89 + +{"metrics":{"latencyMs":1311},"output":{"message":{"content":[{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_0HvrFMK50GvjaGQF2cskFH","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":628,"outputTokens":86,"serverToolUsage":{},"totalTokens":714}}1156 512 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-haiku-4-5-20251001-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 853 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_0HvrFMK50GvjaGQF2cskFH"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_0HvrFMK50GvjaGQF2cskFH"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 347 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:01:30 GMT +X-Amzn-Requestid: d4d8b21f-40f3-426f-b66b-1146a72a78e1 + +{"metrics":{"latencyMs":1119},"output":{"message":{"content":[{"text":"The result of 15 * 8 is **120**."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":727,"outputTokens":17,"serverToolUsage":{},"totalTokens":744}}878 611 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 574 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 446 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:01:38 GMT +X-Amzn-Requestid: d74dd5ff-ee88-4e64-a38c-ae4ab12713a1 + +{"metrics":{"latencyMs":2084},"output":{"message":{"content":[{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_2mOVV8liCIWg1lN51HiyNM","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":628,"outputTokens":85,"serverToolUsage":{},"totalTokens":713}}1157 496 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 853 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_2mOVV8liCIWg1lN51HiyNM"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_2mOVV8liCIWg1lN51HiyNM"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 331 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:01:56 GMT +X-Amzn-Requestid: 94d40744-0f2e-4677-bae7-af5e6c44685f + +{"metrics":{"latencyMs":1626},"output":{"message":{"content":[{"text":"15 * 8 = **120**"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":727,"outputTokens":13,"serverToolUsage":{},"totalTokens":740}}876 611 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-1-20250805-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 574 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 446 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:02:08 GMT +X-Amzn-Requestid: 3c3d13da-6533-4e6f-895f-a832d991429b + +{"metrics":{"latencyMs":5542},"output":{"message":{"content":[{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_UpVvvudZcCsi7uENeqkh28","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":445,"outputTokens":85,"serverToolUsage":{},"totalTokens":530}}1155 336 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-1-20250805-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 853 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_UpVvvudZcCsi7uENeqkh28"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_UpVvvudZcCsi7uENeqkh28"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 429 Too Many Requests +Content-Length: 65 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:02:24 GMT +X-Amzn-Errortype: ThrottlingException:http://internal.amazon.com/coral/com.amazon.bedrock/ +X-Amzn-Requestid: f30357b9-c08f-4fae-9e87-4ebc318676ae + +{"message":"Too many requests, please wait before trying again."}1155 336 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-1-20250805-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 853 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_UpVvvudZcCsi7uENeqkh28"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_UpVvvudZcCsi7uENeqkh28"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 429 Too Many Requests +Content-Length: 65 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:02:27 GMT +X-Amzn-Errortype: ThrottlingException:http://internal.amazon.com/coral/com.amazon.bedrock/ +X-Amzn-Requestid: a81b37bf-ce19-47bd-b2ce-65980cf44fa5 + +{"message":"Too many requests, please wait before trying again."}1155 336 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-1-20250805-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 853 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_UpVvvudZcCsi7uENeqkh28"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_UpVvvudZcCsi7uENeqkh28"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 429 Too Many Requests +Content-Length: 65 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:02:29 GMT +X-Amzn-Errortype: ThrottlingException:http://internal.amazon.com/coral/com.amazon.bedrock/ +X-Amzn-Requestid: de012399-0645-4352-ba84-be5cad73bca0 + +{"message":"Too many requests, please wait before trying again."}876 653 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-20250514-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr Content-Length: 574 @@ -234,80 +349,24 @@ Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK Content-Length: 488 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:39:56 GMT -X-Amzn-Requestid: b8902e91-920a-4e12-8a20-8a308698b57f +Date: Tue, 03 Mar 2026 17:02:33 GMT +X-Amzn-Requestid: c8eab77f-2e2c-47f1-93a5-2b85e6ea142e -{"metrics":{"latencyMs":6297},"output":{"message":{"content":[{"text":"I'll calculate 15 * 8 for you."},{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_6wshjV5LRxSyHTElNv5mbA","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":445,"outputTokens":99,"serverToolUsage":{},"totalTokens":544}}1114 492 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-opus-4-20250514-v1%3A0/converse HTTP/1.1 +{"metrics":{"latencyMs":2529},"output":{"message":{"content":[{"text":"I'll calculate 15 * 8 for you."},{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_LBtQdU6wz1R5WeS6ohdnIj","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":445,"outputTokens":99,"serverToolUsage":{},"totalTokens":544}}1155 492 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-20250514-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr -Content-Length: 814 +Content-Length: 853 Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json -{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{},"name":"calculator","toolUseId":"tooluse_6wshjV5LRxSyHTElNv5mbA"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_6wshjV5LRxSyHTElNv5mbA"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_LBtQdU6wz1R5WeS6ohdnIj"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_LBtQdU6wz1R5WeS6ohdnIj"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK Content-Length: 327 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:40:00 GMT -X-Amzn-Requestid: b635123e-b6f1-442f-9f48-7c7ecf853ef5 +Date: Tue, 03 Mar 2026 17:02:51 GMT +X-Amzn-Requestid: d2c1d8e9-c850-4338-9c54-2b13dbc422cf -{"metrics":{"latencyMs":3127},"output":{"message":{"content":[{"text":"15 * 8 = 120"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":493,"outputTokens":12,"serverToolUsage":{},"totalTokens":505}}876 653 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-20250514-v1%3A0/converse HTTP/1.1 -Host: bedrock-runtime.us-east-1.amazonaws.com -User-Agent: langchaingo-httprr -Content-Length: 574 -Authorization: AWS4-HMAC-SHA256 test-api-key -Content-Type: application/json - -{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK -Content-Length: 488 -Content-Type: application/json -Date: Fri, 23 Jan 2026 13:40:03 GMT -X-Amzn-Requestid: 75041c74-fb4e-41ea-a091-4a008f98b156 - -{"metrics":{"latencyMs":1317},"output":{"message":{"content":[{"text":"I'll calculate 15 * 8 for you."},{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_jygB95lURB2E530Sg9MXGg","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":445,"outputTokens":99,"serverToolUsage":{},"totalTokens":544}}1116 511 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-20250514-v1%3A0/converse HTTP/1.1 -Host: bedrock-runtime.us-east-1.amazonaws.com -User-Agent: langchaingo-httprr -Content-Length: 814 -Authorization: AWS4-HMAC-SHA256 test-api-key -Content-Type: application/json - -{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{},"name":"calculator","toolUseId":"tooluse_jygB95lURB2E530Sg9MXGg"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_jygB95lURB2E530Sg9MXGg"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK -Content-Length: 346 -Content-Type: application/json -Date: Fri, 23 Jan 2026 13:40:05 GMT -X-Amzn-Requestid: 53bac7bd-095f-4572-82ec-6b03a5c022fa - -{"metrics":{"latencyMs":787},"output":{"message":{"content":[{"text":"The result of 15 * 8 is **120**."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":493,"outputTokens":17,"serverToolUsage":{},"totalTokens":510}}878 680 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-7-sonnet-20250219-v1%3A0/converse HTTP/1.1 -Host: bedrock-runtime.us-east-1.amazonaws.com -User-Agent: langchaingo-httprr -Content-Length: 574 -Authorization: AWS4-HMAC-SHA256 test-api-key -Content-Type: application/json - -{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK -Content-Length: 515 -Content-Type: application/json -Date: Fri, 23 Jan 2026 13:40:09 GMT -X-Amzn-Requestid: 72afee62-f8d7-4b69-b310-5e0693e09d07 - -{"metrics":{"latencyMs":3366},"output":{"message":{"content":[{"text":"I'll calculate 15 * 8 for you using the calculator tool."},{"toolUse":{"input":{"a":15,"b":8,"operation":"multiply"},"name":"calculator","toolUseId":"tooluse_JAzSG41ASNalAHsNxaRZAw","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":445,"outputTokens":103,"serverToolUsage":{},"totalTokens":548}}1118 508 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-7-sonnet-20250219-v1%3A0/converse HTTP/1.1 -Host: bedrock-runtime.us-east-1.amazonaws.com -User-Agent: langchaingo-httprr -Content-Length: 814 -Authorization: AWS4-HMAC-SHA256 test-api-key -Content-Type: application/json - -{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{},"name":"calculator","toolUseId":"tooluse_JAzSG41ASNalAHsNxaRZAw"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_JAzSG41ASNalAHsNxaRZAw"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK -Content-Length: 343 -Content-Type: application/json -Date: Fri, 23 Jan 2026 13:40:12 GMT -X-Amzn-Requestid: 729e385a-a68b-449c-9b23-40696cbcdf8a - -{"metrics":{"latencyMs":1499},"output":{"message":{"content":[{"text":"The result of 15 * 8 is 120."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":492,"outputTokens":18,"serverToolUsage":{},"totalTokens":510}}877 693 +{"metrics":{"latencyMs":2397},"output":{"message":{"content":[{"text":"15 * 8 = 120"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":544,"outputTokens":12,"serverToolUsage":{},"totalTokens":556}}877 693 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-5-haiku-20241022-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -318,24 +377,24 @@ Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK Content-Length: 528 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:40:15 GMT -X-Amzn-Requestid: 2778cdc3-abc0-4cbd-9b32-f11b2f33e359 +Date: Tue, 03 Mar 2026 17:02:59 GMT +X-Amzn-Requestid: 2b4ef6f4-ab95-491c-8699-2d3579b63c98 -{"metrics":{"latencyMs":2187},"output":{"message":{"content":[{"text":"I'll help you calculate 15 multiplied by 8 using the calculator tool."},{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_JTEzhwB_Shy56QQI4lV9sQ","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":396,"outputTokens":105,"serverToolUsage":{},"totalTokens":501}}1117 578 +{"metrics":{"latencyMs":1915},"output":{"message":{"content":[{"text":"I'll help you calculate 15 multiplied by 8 using the calculator tool."},{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_BnHGFzo8AoF6yDpiPwuY63","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":396,"outputTokens":105,"serverToolUsage":{},"totalTokens":501}}1156 507 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-5-haiku-20241022-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr -Content-Length: 814 +Content-Length: 853 Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json -{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{},"name":"calculator","toolUseId":"tooluse_JTEzhwB_Shy56QQI4lV9sQ"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_JTEzhwB_Shy56QQI4lV9sQ"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK -Content-Length: 413 +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_BnHGFzo8AoF6yDpiPwuY63"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_BnHGFzo8AoF6yDpiPwuY63"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 342 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:40:17 GMT -X-Amzn-Requestid: 7bfb242c-ccd3-4232-85ff-437728b6cd39 +Date: Tue, 03 Mar 2026 17:03:16 GMT +X-Amzn-Requestid: 6cad71f4-b67c-4ea8-8c17-abc9e20f7e20 -{"metrics":{"latencyMs":1214},"output":{"message":{"content":[{"text":"I can confirm that 15 * 8 = 120. I used the calculator tool to multiply these two numbers for you."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":443,"outputTokens":32,"serverToolUsage":{},"totalTokens":475}}860 545 +{"metrics":{"latencyMs":764},"output":{"message":{"content":[{"text":"The result of 15 * 8 is 120."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":494,"outputTokens":18,"serverToolUsage":{},"totalTokens":512}}860 545 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/cohere.command-r-plus-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr @@ -346,21 +405,329 @@ Content-Type: application/json {"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK Content-Length: 380 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:40:21 GMT -X-Amzn-Requestid: d1d96796-6e66-4e1e-9bc1-c688e161097a +Date: Tue, 03 Mar 2026 17:03:24 GMT +X-Amzn-Requestid: 7fb892a4-434c-49cb-8eef-87504a55064b -{"metrics":{"latencyMs":2108},"output":{"message":{"content":[{"text":"I will use the calculator tool to multiply 15 and 8."},{"toolUse":{"input":{"a":15,"b":8,"operation":"multiply"},"name":"calculator","toolUseId":"tooluse_EZaDYqSSRDyTnGgSQK1Cug"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":39,"outputTokens":30,"serverToolUsage":{},"totalTokens":69}}1100 389 +{"metrics":{"latencyMs":2072},"output":{"message":{"content":[{"text":"I will use the calculator tool to multiply 15 and 8."},{"toolUse":{"input":{"a":15,"b":8,"operation":"multiply"},"name":"calculator","toolUseId":"tooluse_jrsLqewNLRB5g9loWRJPrd"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":39,"outputTokens":30,"serverToolUsage":{},"totalTokens":69}}1139 389 POST https://bedrock-runtime.us-east-1.amazonaws.com/model/cohere.command-r-plus-v1%3A0/converse HTTP/1.1 Host: bedrock-runtime.us-east-1.amazonaws.com User-Agent: langchaingo-httprr -Content-Length: 814 +Content-Length: 853 Authorization: AWS4-HMAC-SHA256 test-api-key Content-Type: application/json -{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{},"name":"calculator","toolUseId":"tooluse_EZaDYqSSRDyTnGgSQK1Cug"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_EZaDYqSSRDyTnGgSQK1Cug"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_jrsLqewNLRB5g9loWRJPrd"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_jrsLqewNLRB5g9loWRJPrd"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK Content-Length: 224 Content-Type: application/json -Date: Fri, 23 Jan 2026 13:40:23 GMT -X-Amzn-Requestid: cb84d2fe-a47f-472d-9a62-09f6a9f11bd3 +Date: Tue, 03 Mar 2026 17:03:42 GMT +X-Amzn-Requestid: a807f650-5c9f-4c7f-b180-b04143e5202a -{"metrics":{"latencyMs":1523},"output":{"message":{"content":[{"text":"The answer is **120**."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":51,"outputTokens":8,"serverToolUsage":{},"totalTokens":59}} \ No newline at end of file +{"metrics":{"latencyMs":1540},"output":{"message":{"content":[{"text":"The answer is **120**."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":51,"outputTokens":8,"serverToolUsage":{},"totalTokens":59}}845 541 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/deepseek.v3.2/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 574 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 376 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:03:51 GMT +X-Amzn-Requestid: ddffb646-5eb2-4597-a1d3-9b4024fac4f7 + +{"metrics":{"latencyMs":2769},"output":{"message":{"content":[{"text":"I'll calculate 15 multiplied by 8 for you.\n\n"},{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_334wv9zhg7tzewY9cqMWeA"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":375,"outputTokens":87,"serverToolUsage":{},"totalTokens":462}}1124 382 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/deepseek.v3.2/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 853 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_334wv9zhg7tzewY9cqMWeA"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_334wv9zhg7tzewY9cqMWeA"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 217 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:04:12 GMT +X-Amzn-Requestid: be2e88be-834a-4e70-a4ca-f885ec790b30 + +{"metrics":{"latencyMs":4368},"output":{"message":{"content":[{"text":"15 × 8 = 120"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":468,"outputTokens":8,"serverToolUsage":{},"totalTokens":476}}857 592 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/openai.gpt-oss-120b-1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 574 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 427 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:04:18 GMT +X-Amzn-Requestid: 6ac40649-f91a-4e0e-94f8-ff370356f625 + +{"metrics":{"latencyMs":338},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"text":"We need to calculate 15 * 8 = 120. Use calculator function."}}},{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_fsETLVAPPAiK8P5CQ95KEZ"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":159,"outputTokens":59,"serverToolUsage":{},"totalTokens":218}}1136 529 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/openai.gpt-oss-120b-1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 853 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_fsETLVAPPAiK8P5CQ95KEZ"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_fsETLVAPPAiK8P5CQ95KEZ"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 364 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:04:35 GMT +X-Amzn-Requestid: 91d7ae30-c3db-4161-a51a-7f67727f53fb + +{"metrics":{"latencyMs":557},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"text":"The user asks to calculate 15 * 8. We have the result 120. Need to output final answer."}}},{"text":"15 × 8 = 120."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":198,"outputTokens":44,"serverToolUsage":{},"totalTokens":242}}856 568 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/openai.gpt-oss-20b-1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 574 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 403 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:04:42 GMT +X-Amzn-Requestid: 85bc2d9f-5c83-40bf-977e-fb52c3d8e686 + +{"metrics":{"latencyMs":657},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"text":"We need to use the calculator tool."}}},{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_uNWH7xzECAH8tqzW9ON8gC"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":159,"outputTokens":40,"serverToolUsage":{},"totalTokens":199}}1135 563 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/openai.gpt-oss-20b-1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 853 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_uNWH7xzECAH8tqzW9ON8gC"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_uNWH7xzECAH8tqzW9ON8gC"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 398 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:04:58 GMT +X-Amzn-Requestid: f438b693-dd8b-498a-ab3e-829c97cacf1a + +{"metrics":{"latencyMs":301},"output":{"message":{"content":[{"reasoningContent":{"reasoningText":{"text":"The user asked to calculate 15 * 8. The assistant already did. Possibly they want the result. The final answer is 120. So respond with that."}}},{"text":"120"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":198,"outputTokens":45,"serverToolUsage":{},"totalTokens":243}}855 483 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/qwen.qwen3-next-80b-a3b/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 574 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 318 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:05:05 GMT +X-Amzn-Requestid: d4e278e0-8c7c-4e51-bc78-7b803669c5b1 + +{"metrics":{"latencyMs":1033},"output":{"message":{"content":[{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_4vv10vuf06MMOcflIltWAI"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":221,"outputTokens":32,"serverToolUsage":{},"totalTokens":253}}1134 409 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/qwen.qwen3-next-80b-a3b/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 853 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_4vv10vuf06MMOcflIltWAI"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_4vv10vuf06MMOcflIltWAI"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 244 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:05:22 GMT +X-Amzn-Requestid: c3997954-0f19-4e79-8213-3e13ef219f86 + +{"metrics":{"latencyMs":515},"output":{"message":{"content":[{"text":"The result of 15 multiplied by 8 is 120."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":270,"outputTokens":17,"serverToolUsage":{},"totalTokens":287}}855 482 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/qwen.qwen3-vl-235b-a22b/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 574 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 317 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:05:29 GMT +X-Amzn-Requestid: 08d165d9-9b07-4615-b07d-c490ae80a223 + +{"metrics":{"latencyMs":806},"output":{"message":{"content":[{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_uWA2ORAozJQdxtIuJ5UKRO"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":221,"outputTokens":32,"serverToolUsage":{},"totalTokens":253}}1134 401 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/qwen.qwen3-vl-235b-a22b/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 853 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_uWA2ORAozJQdxtIuJ5UKRO"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_uWA2ORAozJQdxtIuJ5UKRO"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 236 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:05:46 GMT +X-Amzn-Requestid: 9de9b4ac-d7ae-4b6a-909c-d7ec9b37f55a + +{"metrics":{"latencyMs":575},"output":{"message":{"content":[{"text":"The result of 15 * 8 is **120**."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":269,"outputTokens":17,"serverToolUsage":{},"totalTokens":286}}853 483 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/qwen.qwen3-32b-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 574 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 318 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:05:53 GMT +X-Amzn-Requestid: f2e8aea1-d8ce-4983-8ff2-8475ae387b5f + +{"metrics":{"latencyMs":1407},"output":{"message":{"content":[{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_47IkYlf21JuVlGZosNMnLs"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":225,"outputTokens":32,"serverToolUsage":{},"totalTokens":257}}1132 410 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/qwen.qwen3-32b-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 853 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_47IkYlf21JuVlGZosNMnLs"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_47IkYlf21JuVlGZosNMnLs"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 245 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:06:11 GMT +X-Amzn-Requestid: 345e1b55-a3a7-4d5c-b0a9-dd021935f44c + +{"metrics":{"latencyMs":1548},"output":{"message":{"content":[{"text":"The result of $15 \\times 8$ is **120**."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":273,"outputTokens":19,"serverToolUsage":{},"totalTokens":292}}863 482 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/qwen.qwen3-coder-30b-a3b-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 574 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 317 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:06:18 GMT +X-Amzn-Requestid: 14ba6298-e034-45a8-b2d1-0a02b72b39f1 + +{"metrics":{"latencyMs":665},"output":{"message":{"content":[{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_aGFNJ9ZFYfo3CogYV34tSZ"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":378,"outputTokens":41,"serverToolUsage":{},"totalTokens":419}}1142 407 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/qwen.qwen3-coder-30b-a3b-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 853 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_aGFNJ9ZFYfo3CogYV34tSZ"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_aGFNJ9ZFYfo3CogYV34tSZ"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 242 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:06:34 GMT +X-Amzn-Requestid: 941f4f7a-ed2d-43ba-8416-e8275ffed7e1 + +{"metrics":{"latencyMs":277},"output":{"message":{"content":[{"text":"The result of $15 \\times 8$ is $120$."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":436,"outputTokens":18,"serverToolUsage":{},"totalTokens":454}}853 482 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/qwen.qwen3-coder-next/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 574 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 317 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:06:41 GMT +X-Amzn-Requestid: 249e17c8-6743-4f6e-b051-5f5984c3c018 + +{"metrics":{"latencyMs":922},"output":{"message":{"content":[{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_gsE4sp1ENzoTMBP50MpFQn"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":377,"outputTokens":41,"serverToolUsage":{},"totalTokens":418}}1132 407 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/qwen.qwen3-coder-next/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 853 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_gsE4sp1ENzoTMBP50MpFQn"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_gsE4sp1ENzoTMBP50MpFQn"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 242 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:06:58 GMT +X-Amzn-Requestid: 08e1fd09-7047-461b-b54a-4cc8bc4d4edb + +{"metrics":{"latencyMs":504},"output":{"message":{"content":[{"text":"The result of $15 \\times 8$ is $120$."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":434,"outputTokens":18,"serverToolUsage":{},"totalTokens":452}}869 482 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/mistral.mistral-large-3-675b-instruct/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 574 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 317 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:07:04 GMT +X-Amzn-Requestid: aec1bb2d-4a44-41d2-a95b-59194f7c1830 + +{"metrics":{"latencyMs":367},"output":{"message":{"content":[{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_l24cvHuahEJ25ry2DVAWxB"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":137,"outputTokens":25,"serverToolUsage":{},"totalTokens":162}}1148 415 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/mistral.mistral-large-3-675b-instruct/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 853 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_l24cvHuahEJ25ry2DVAWxB"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_l24cvHuahEJ25ry2DVAWxB"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 250 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:07:21 GMT +X-Amzn-Requestid: 74e955f4-afc8-463b-9a1d-5d844bf5ad59 + +{"metrics":{"latencyMs":348},"output":{"message":{"content":[{"text":"The result of \\( 15 \\times 8 \\) is **120**."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":168,"outputTokens":20,"serverToolUsage":{},"totalTokens":188}}865 483 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/mistral.mistral-large-2402-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 574 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 318 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:07:29 GMT +X-Amzn-Requestid: de693b74-d0d7-4211-ba59-01bfb0da5737 + +{"metrics":{"latencyMs":1550},"output":{"message":{"content":[{"toolUse":{"input":{"operation":"multiply","a":15,"b":8},"name":"calculator","toolUseId":"tooluse_yq4pDEXFcOgzF2ZgkAeP6U"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":143,"outputTokens":35,"serverToolUsage":{},"totalTokens":178}}1144 397 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/mistral.mistral-large-2402-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 853 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_yq4pDEXFcOgzF2ZgkAeP6U"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_yq4pDEXFcOgzF2ZgkAeP6U"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 232 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:07:45 GMT +X-Amzn-Requestid: ba7aea39-cc5d-485f-90d7-4a6047ae559b + +{"metrics":{"latencyMs":455},"output":{"message":{"content":[{"text":"The result of 15 * 8 is 120."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":195,"outputTokens":16,"serverToolUsage":{},"totalTokens":211}}852 483 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/moonshotai.kimi-k2.5/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 574 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 318 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:07:53 GMT +X-Amzn-Requestid: 810d587d-7116-4631-9540-9599830932d1 + +{"metrics":{"latencyMs":1818},"output":{"message":{"content":[{"toolUse":{"input":{"a":15,"b":8,"operation":"multiply"},"name":"calculator","toolUseId":"tooluse_sutJQ3XHuccpwovkFsTXJ2"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":114,"outputTokens":29,"serverToolUsage":{},"totalTokens":143}}1131 402 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/moonshotai.kimi-k2.5/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 853 +Authorization: AWS4-HMAC-SHA256 test-api-key +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Calculate 15 * 8"}],"role":"user"},{"content":[{"toolUse":{"input":{"a":"15","b":"8","operation":"multiply"},"name":"calculator","toolUseId":"tooluse_sutJQ3XHuccpwovkFsTXJ2"}}],"role":"assistant"},{"content":[{"toolResult":{"content":[{"text":"120"}],"toolUseId":"tooluse_sutJQ3XHuccpwovkFsTXJ2"}}],"role":"user"}],"toolConfig":{"toolChoice":{"auto":{}},"tools":[{"toolSpec":{"description":"A calculator that can perform basic arithmetic operations","inputSchema":{"json":{"type":"object","properties":{"operation":{"type":"string","description":"The operation to perform","enum":["add","subtract","multiply","divide"]},"a":{"type":"number","description":"First number"},"b":{"type":"number","description":"Second number"}},"required":["operation","a","b"]}},"name":"calculator"}}]}}HTTP/2.0 200 OK +Content-Length: 237 +Content-Type: application/json +Date: Tue, 03 Mar 2026 17:08:10 GMT +X-Amzn-Requestid: 7c911a3d-b6e0-4322-a217-852ae959806c + +{"metrics":{"latencyMs":542},"output":{"message":{"content":[{"text":" The result of 15 * 8 is **120**."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":184,"outputTokens":13,"serverToolUsage":{},"totalTokens":197}} \ No newline at end of file diff --git a/llms/bedrock/testdata/TestAmazonToolCallingStreamingConverseAPI.httprr b/llms/bedrock/testdata/TestAmazonToolCallingStreamingConverseAPI.httprr index 3e86cb98f93bd19d49aea0c151d18e0868eb304b..7ae2913f037448a96b7845ac102b73a1ffa2f78a 100644 GIT binary patch literal 161032 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 diff --git a/llms/bedrock/testdata/TestBedrockAnthropicToolCalling.httprr b/llms/bedrock/testdata/TestBedrockAnthropicToolCalling.httprr deleted file mode 100644 index 5a6284cf..00000000 --- a/llms/bedrock/testdata/TestBedrockAnthropicToolCalling.httprr +++ /dev/null @@ -1,56 +0,0 @@ -httprr trace v1 -821 762 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-haiku-4-5-20251001-v1%3A0/invoke HTTP/1.1 -Host: bedrock-runtime.us-east-1.amazonaws.com -User-Agent: langchaingo-httprr -Content-Length: 507 -Accept: */* -Authorization: AWS4-HMAC-SHA256 test-api-key -Content-Type: application/json - -{"anthropic_version":"bedrock-2023-05-31","max_tokens":512,"messages":[{"role":"user","content":[{"type":"text","text":"What's the weather like in New York?"}]}],"tools":[{"name":"get_weather","description":"Get the current weather for a location","input_schema":{"properties":{"location":{"description":"The city and state, e.g. San Francisco, CA","type":"string"},"unit":{"description":"The unit of temperature","enum":["celsius","fahrenheit"],"type":"string"}},"required":["location"],"type":"object"}}]}HTTP/2.0 200 OK -Content-Length: 479 -Content-Type: application/json -Date: Fri, 23 Jan 2026 12:46:58 GMT -X-Amzn-Bedrock-Input-Token-Count: 614 -X-Amzn-Bedrock-Invocation-Latency: 763 -X-Amzn-Bedrock-Output-Token-Count: 57 -X-Amzn-Requestid: be9df7d2-bf07-4936-a89d-5c9a2048fd12 - -{"model":"claude-haiku-4-5-20251001","id":"msg_bdrk_01WuVdmuVpN7jMutExtqSqDR","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_bdrk_01NAFKQXKFq9KJcXYspsWJT2","name":"get_weather","input":{"location":"New York, NY"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":614,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":57}}787 793 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-haiku-4-5-20251001-v1%3A0/invoke HTTP/1.1 -Host: bedrock-runtime.us-east-1.amazonaws.com -User-Agent: langchaingo-httprr -Content-Length: 473 -Accept: */* -Authorization: AWS4-HMAC-SHA256 test-api-key -Content-Type: application/json - -{"anthropic_version":"bedrock-2023-05-31","max_tokens":512,"messages":[{"role":"user","content":[{"type":"text","text":"What's the weather like in New York?"}]},{"role":"assistant","content":[{"type":"tool_use","id":"toolu_bdrk_01NAFKQXKFq9KJcXYspsWJT2","name":"get_weather","input":{"location":"New York, NY"}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_01NAFKQXKFq9KJcXYspsWJT2","content":"It's currently 72°F and sunny in New York"}]}]}HTTP/2.0 200 OK -Content-Length: 511 -Content-Type: application/json -Date: Fri, 23 Jan 2026 12:47:00 GMT -X-Amzn-Bedrock-Input-Token-Count: 97 -X-Amzn-Bedrock-Invocation-Latency: 790 -X-Amzn-Bedrock-Output-Token-Count: 35 -X-Amzn-Requestid: 4c43be74-cdfc-4462-a8a9-be68cad26a23 - -{"model":"claude-haiku-4-5-20251001","id":"msg_bdrk_01UXSrEUQrxZ8DSJNTGEW4SC","type":"message","role":"assistant","content":[{"type":"text","text":"It's currently **72°F and sunny** in New York. It's nice weather! Is there anything else you'd like to know about the weather?"}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":97,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":35}}1066 980 -POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-haiku-4-5-20251001-v1%3A0/invoke HTTP/1.1 -Host: bedrock-runtime.us-east-1.amazonaws.com -User-Agent: langchaingo-httprr -Content-Length: 752 -Accept: */* -Authorization: AWS4-HMAC-SHA256 test-api-key -Content-Type: application/json - -{"anthropic_version":"bedrock-2023-05-31","max_tokens":512,"messages":[{"role":"user","content":[{"type":"text","text":"What's 123 * 456 and what's the weather in Paris?"}]}],"tools":[{"name":"get_weather","description":"Get the current weather for a location","input_schema":{"properties":{"location":{"description":"The city and state, e.g. San Francisco, CA","type":"string"},"unit":{"description":"The unit of temperature","enum":["celsius","fahrenheit"],"type":"string"}},"required":["location"],"type":"object"}},{"name":"calculate","description":"Perform mathematical calculations","input_schema":{"properties":{"expression":{"description":"The mathematical expression to evaluate","type":"string"}},"required":["expression"],"type":"object"}}]}HTTP/2.0 200 OK -Content-Length: 696 -Content-Type: application/json -Date: Fri, 23 Jan 2026 12:47:02 GMT -X-Amzn-Bedrock-Input-Token-Count: 682 -X-Amzn-Bedrock-Invocation-Latency: 930 -X-Amzn-Bedrock-Output-Token-Count: 108 -X-Amzn-Requestid: 228f3dbd-385f-486b-b9b3-3b364932798f - -{"model":"claude-haiku-4-5-20251001","id":"msg_bdrk_0122fRnppVApgaxwsVmbDSx9","type":"message","role":"assistant","content":[{"type":"text","text":"I'll calculate that multiplication and get the weather in Paris for you."},{"type":"tool_use","id":"toolu_bdrk_01X6jfbj9zs3QKzaXqnxgv6w","name":"calculate","input":{"expression":"123 * 456"}},{"type":"tool_use","id":"toolu_bdrk_01Qmb6fa8KLEBr2MVnKyAUWy","name":"get_weather","input":{"location":"Paris, France"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":682,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":108}} \ No newline at end of file diff --git a/llms/bedrock/testdata/TestCreateClientWithBearerTokenCredentials.httprr b/llms/bedrock/testdata/TestCreateClientWithBearerTokenCredentials.httprr new file mode 100644 index 00000000..c13b0f3b --- /dev/null +++ b/llms/bedrock/testdata/TestCreateClientWithBearerTokenCredentials.httprr @@ -0,0 +1,15 @@ +httprr trace v1 +367 586 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 109 +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Hello, how are you?"}],"role":"user"}]}HTTP/2.0 200 OK +Content-Length: 421 +Content-Type: application/json +Date: Tue, 03 Mar 2026 21:46:55 GMT +X-Amzn-Requestid: f8c7b8ae-9387-4864-9245-d97c1c081613 + +{"metrics":{"latencyMs":2193},"output":{"message":{"content":[{"text":"Hello! I'm doing well, thank you for asking. How are you doing today? Is there anything I can help you with?"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":13,"outputTokens":30,"serverToolUsage":{},"totalTokens":43}} \ No newline at end of file diff --git a/llms/bedrock/testdata/TestCreateClientWithLongLeavingCredentials.httprr b/llms/bedrock/testdata/TestCreateClientWithLongLeavingCredentials.httprr new file mode 100644 index 00000000..a0e2b031 --- /dev/null +++ b/llms/bedrock/testdata/TestCreateClientWithLongLeavingCredentials.httprr @@ -0,0 +1,15 @@ +httprr trace v1 +367 586 +POST https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-5-20250929-v1%3A0/converse HTTP/1.1 +Host: bedrock-runtime.us-east-1.amazonaws.com +User-Agent: langchaingo-httprr +Content-Length: 109 +Content-Type: application/json + +{"inferenceConfig":{"maxTokens":512},"messages":[{"content":[{"text":"Hello, how are you?"}],"role":"user"}]}HTTP/2.0 200 OK +Content-Length: 421 +Content-Type: application/json +Date: Tue, 03 Mar 2026 21:50:40 GMT +X-Amzn-Requestid: 9847ea7d-909f-4d65-b1be-4ec486cfec87 + +{"metrics":{"latencyMs":2036},"output":{"message":{"content":[{"text":"Hello! I'm doing well, thank you for asking. How are you doing today? Is there anything I can help you with?"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":13,"outputTokens":30,"serverToolUsage":{},"totalTokens":43}} \ No newline at end of file