diff --git a/LICENSES/APACHE-2.0.txt b/LICENSES/APACHE-2.0.txt new file mode 100644 index 000000000..7a4a3ea24 --- /dev/null +++ b/LICENSES/APACHE-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/NOTICE b/NOTICE new file mode 100644 index 000000000..a2662b740 --- /dev/null +++ b/NOTICE @@ -0,0 +1,31 @@ +RubyLLM Project +Copyright 2025 Carmine Paolino. All Rights Reserved. +Licensed under the MIT License. + +This project includes software developed by third parties, licensed under +terms compatible with the MIT License. The required notices and license +texts are included below and/or in the LICENSES/ directory. + +-------------------------------------------------------------------------- + +This project incorporates code from aws-sdk-ruby. +The original NOTICE file for aws-sdk-ruby contains the following: + + --- BEGIN aws-sdk-ruby NOTICE --- + AWS SDK for Ruby + Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + --- END aws-sdk-ruby NOTICE --- + +The aws-sdk-ruby components used in this project are licensed under the +Apache License, Version 2.0 (the "License"). You may obtain a copy of +the License at: + + LICENSES/APACHE-2.0.txt + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +-------------------------------------------------------------------------- diff --git a/README.md b/README.md index f7da4bbd9..1b9cb15cd 100644 --- a/README.md +++ b/README.md @@ -99,10 +99,14 @@ Configure with your API keys: ```ruby RubyLLM.configure do |config| - config.openai_api_key = ENV['OPENAI_API_KEY'] - config.anthropic_api_key = ENV['ANTHROPIC_API_KEY'] - config.gemini_api_key = ENV['GEMINI_API_KEY'] - config.deepseek_api_key = ENV['DEEPSEEK_API_KEY'] + config.openai_api_key = ENV.fetch('OPENAI_API_KEY', nil) + config.anthropic_api_key = ENV.fetch('ANTHROPIC_API_KEY', nil) + config.gemini_api_key = ENV.fetch('GEMINI_API_KEY', nil) + config.deepseek_api_key = ENV.fetch('DEEPSEEK_API_KEY', nil) + config.bedrock_api_key = ENV.fetch('AWS_ACCESS_KEY_ID', nil) + config.bedrock_secret_key = ENV.fetch('AWS_SECRET_ACCESS_KEY', nil) + config.bedrock_region = ENV.fetch('AWS_REGION', nil) + config.bedrock_session_token = ENV.fetch('AWS_SESSION_TOKEN', nil) end ``` diff --git a/bin/console b/bin/console index e43cf3d8a..b5e871689 100755 --- a/bin/console +++ b/bin/console @@ -12,6 +12,10 @@ RubyLLM.configure do |config| config.anthropic_api_key = ENV.fetch('ANTHROPIC_API_KEY', nil) config.gemini_api_key = ENV.fetch('GEMINI_API_KEY', nil) config.deepseek_api_key = ENV.fetch('DEEPSEEK_API_KEY', nil) + config.bedrock_api_key = ENV.fetch('AWS_ACCESS_KEY_ID', nil) + config.bedrock_secret_key = ENV.fetch('AWS_SECRET_ACCESS_KEY', nil) + config.bedrock_region = ENV.fetch('AWS_REGION', nil) + config.bedrock_session_token = ENV.fetch('AWS_SESSION_TOKEN', nil) end IRB.start(__FILE__) diff --git a/docs/guides/getting-started.md b/docs/guides/getting-started.md index ff6cb1c0b..07cb5e460 100644 --- a/docs/guides/getting-started.md +++ b/docs/guides/getting-started.md @@ -26,10 +26,14 @@ require 'ruby_llm' RubyLLM.configure do |config| # Add the API keys you have available - config.openai_api_key = ENV['OPENAI_API_KEY'] - config.anthropic_api_key = ENV['ANTHROPIC_API_KEY'] - config.gemini_api_key = ENV['GEMINI_API_KEY'] - config.deepseek_api_key = ENV['DEEPSEEK_API_KEY'] + config.openai_api_key = ENV.fetch('OPENAI_API_KEY', nil) + config.anthropic_api_key = ENV.fetch('ANTHROPIC_API_KEY', nil) + config.gemini_api_key = ENV.fetch('GEMINI_API_KEY', nil) + config.deepseek_api_key = ENV.fetch('DEEPSEEK_API_KEY', nil) + config.bedrock_api_key = ENV.fetch('AWS_ACCESS_KEY_ID', nil) + config.bedrock_secret_key = ENV.fetch('AWS_SECRET_ACCESS_KEY', nil) + config.bedrock_region = ENV.fetch('AWS_REGION', nil) + config.bedrock_session_token = ENV.fetch('AWS_SESSION_TOKEN', nil) end ``` diff --git a/docs/guides/rails.md b/docs/guides/rails.md index ec36e4070..4eb8108d3 100644 --- a/docs/guides/rails.md +++ b/docs/guides/rails.md @@ -92,10 +92,14 @@ In an initializer (e.g., `config/initializers/ruby_llm.rb`): ```ruby RubyLLM.configure do |config| - config.openai_api_key = ENV['OPENAI_API_KEY'] - config.anthropic_api_key = ENV['ANTHROPIC_API_KEY'] - config.gemini_api_key = ENV['GEMINI_API_KEY'] - config.deepseek_api_key = ENV['DEEPSEEK_API_KEY'] + config.openai_api_key = ENV.fetch('OPENAI_API_KEY', nil) + config.anthropic_api_key = ENV.fetch('ANTHROPIC_API_KEY', nil) + config.gemini_api_key = ENV.fetch('GEMINI_API_KEY', nil) + config.deepseek_api_key = ENV.fetch('DEEPSEEK_API_KEY', nil) + config.bedrock_api_key = ENV.fetch('AWS_ACCESS_KEY_ID', nil) + config.bedrock_secret_key = ENV.fetch('AWS_SECRET_ACCESS_KEY', nil) + config.bedrock_region = ENV.fetch('AWS_REGION', nil) + config.bedrock_session_token = ENV.fetch('AWS_SESSION_TOKEN', nil) end ``` diff --git a/docs/installation.md b/docs/installation.md index aac4f32fb..7fc021c7c 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -51,10 +51,14 @@ require 'ruby_llm' RubyLLM.configure do |config| # Required: At least one API key - config.openai_api_key = ENV['OPENAI_API_KEY'] - config.anthropic_api_key = ENV['ANTHROPIC_API_KEY'] - config.gemini_api_key = ENV['GEMINI_API_KEY'] - config.deepseek_api_key = ENV['DEEPSEEK_API_KEY'] + config.openai_api_key = ENV.fetch('OPENAI_API_KEY', nil) + config.anthropic_api_key = ENV.fetch('ANTHROPIC_API_KEY', nil) + config.gemini_api_key = ENV.fetch('GEMINI_API_KEY', nil) + config.deepseek_api_key = ENV.fetch('DEEPSEEK_API_KEY', nil) + config.bedrock_api_key = ENV.fetch('AWS_ACCESS_KEY_ID', nil) + config.bedrock_secret_key = ENV.fetch('AWS_SECRET_ACCESS_KEY', nil) + config.bedrock_region = ENV.fetch('AWS_REGION', nil) + config.bedrock_session_token = ENV.fetch('AWS_SESSION_TOKEN', nil) # Optional: Set default models config.default_model = 'gpt-4o-mini' # Default chat model diff --git a/lib/ruby_llm.rb b/lib/ruby_llm.rb index a58fddce4..70aa4a8cc 100644 --- a/lib/ruby_llm.rb +++ b/lib/ruby_llm.rb @@ -15,7 +15,8 @@ 'llm' => 'LLM', 'openai' => 'OpenAI', 'api' => 'API', - 'deepseek' => 'DeepSeek' + 'deepseek' => 'DeepSeek', + 'bedrock' => 'Bedrock' ) loader.ignore("#{__dir__}/tasks") loader.ignore("#{__dir__}/ruby_llm/railtie") @@ -71,6 +72,7 @@ def logger RubyLLM::Provider.register :anthropic, RubyLLM::Providers::Anthropic RubyLLM::Provider.register :gemini, RubyLLM::Providers::Gemini RubyLLM::Provider.register :deepseek, RubyLLM::Providers::DeepSeek +RubyLLM::Provider.register :bedrock, RubyLLM::Providers::Bedrock if defined?(Rails::Railtie) require 'ruby_llm/railtie' diff --git a/lib/ruby_llm/aliases.json b/lib/ruby_llm/aliases.json index d38bb10f3..18b9a5707 100644 --- a/lib/ruby_llm/aliases.json +++ b/lib/ruby_llm/aliases.json @@ -1,24 +1,39 @@ { "claude-3-5-sonnet": { - "anthropic": "claude-3-5-sonnet-20241022" + "anthropic": "claude-3-5-sonnet-20241022", + "bedrock": "anthropic.claude-3-5-sonnet-20241022-v2:0" }, "claude-3-5-haiku": { - "anthropic": "claude-3-5-haiku-20241022" + "anthropic": "claude-3-5-haiku-20241022", + "bedrock": "anthropic.claude-3-5-haiku-20241022-v1:0" }, "claude-3-7-sonnet": { - "anthropic": "claude-3-7-sonnet-20250219" + "anthropic": "claude-3-7-sonnet-20250219", + "bedrock": "us.anthropic.claude-3-7-sonnet-20250219-v1:0" }, "claude-3-opus": { - "anthropic": "claude-3-opus-20240229" + "anthropic": "claude-3-opus-20240229", + "bedrock": "anthropic.claude-3-opus-20240229-v1:0" }, "claude-3-sonnet": { - "anthropic": "claude-3-sonnet-20240229" + "anthropic": "claude-3-sonnet-20240229", + "bedrock": "anthropic.claude-3-sonnet-20240229-v1:0" }, "claude-3-haiku": { - "anthropic": "claude-3-haiku-20240307" + "anthropic": "claude-3-haiku-20240307", + "bedrock": "anthropic.claude-3-haiku-20240307-v1:0" }, "claude-3": { - "anthropic": "claude-3-sonnet-20240229" + "anthropic": "claude-3-sonnet-20240229", + "bedrock": "anthropic.claude-3-sonnet-20240229-v1:0" + }, + "claude-2": { + "anthropic": "claude-2.0", + "bedrock": "anthropic.claude-2.0" + }, + "claude-2-1": { + "anthropic": "claude-2.1", + "bedrock": "anthropic.claude-2.1" }, "gpt-4o": { "openai": "gpt-4o-2024-11-20" diff --git a/lib/ruby_llm/configuration.rb b/lib/ruby_llm/configuration.rb index 72a878aae..a5a41542b 100644 --- a/lib/ruby_llm/configuration.rb +++ b/lib/ruby_llm/configuration.rb @@ -14,6 +14,10 @@ class Configuration :anthropic_api_key, :gemini_api_key, :deepseek_api_key, + :bedrock_api_key, + :bedrock_secret_key, + :bedrock_region, + :bedrock_session_token, :default_model, :default_embedding_model, :default_image_model, diff --git a/lib/ruby_llm/models.json b/lib/ruby_llm/models.json index bf0d48710..f1c1f0e32 100644 --- a/lib/ruby_llm/models.json +++ b/lib/ruby_llm/models.json @@ -1,4 +1,839 @@ [ + { + "id": "anthropic.claude-3-5-haiku-20241022-v1:0", + "created_at": null, + "display_name": "Claude 3.5 Haiku", + "provider": "bedrock", + "context_window": 4096, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_5_haiku", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 0.8, + "output_price_per_million": 4.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "ON_DEMAND" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-3-5-sonnet-20240620-v1:0", + "created_at": null, + "display_name": "Claude 3.5 Sonnet", + "provider": "bedrock", + "context_window": 4096, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_sonnet", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 3.0, + "output_price_per_million": 15.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "ON_DEMAND" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-3-5-sonnet-20240620-v1:0:18k", + "created_at": null, + "display_name": "Claude 3.5 Sonnet", + "provider": "bedrock", + "context_window": 4096, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_sonnet", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 3.0, + "output_price_per_million": 15.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "PROVISIONED" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-3-5-sonnet-20240620-v1:0:200k", + "created_at": null, + "display_name": "Claude 3.5 Sonnet", + "provider": "bedrock", + "context_window": 4096, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_sonnet", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 3.0, + "output_price_per_million": 15.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "PROVISIONED" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-3-5-sonnet-20240620-v1:0:51k", + "created_at": null, + "display_name": "Claude 3.5 Sonnet", + "provider": "bedrock", + "context_window": 4096, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_sonnet", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 3.0, + "output_price_per_million": 15.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "PROVISIONED" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-3-5-sonnet-20241022-v2:0", + "created_at": null, + "display_name": "Claude 3.5 Sonnet v2", + "provider": "bedrock", + "context_window": 4096, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_sonnet", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 3.0, + "output_price_per_million": 15.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "ON_DEMAND" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-3-5-sonnet-20241022-v2:0:18k", + "created_at": null, + "display_name": "Claude 3.5 Sonnet v2", + "provider": "bedrock", + "context_window": 4096, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_sonnet", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 3.0, + "output_price_per_million": 15.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "PROVISIONED" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-3-5-sonnet-20241022-v2:0:200k", + "created_at": null, + "display_name": "Claude 3.5 Sonnet v2", + "provider": "bedrock", + "context_window": 4096, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_sonnet", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 3.0, + "output_price_per_million": 15.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "PROVISIONED" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-3-5-sonnet-20241022-v2:0:51k", + "created_at": null, + "display_name": "Claude 3.5 Sonnet v2", + "provider": "bedrock", + "context_window": 4096, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_sonnet", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 3.0, + "output_price_per_million": 15.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "PROVISIONED" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "us.anthropic.claude-3-7-sonnet-20250219-v1:0", + "created_at": null, + "display_name": "Claude 3.7 Sonnet", + "provider": "bedrock", + "context_window": 4096, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_sonnet", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 3.0, + "output_price_per_million": 15.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "INFERENCE_PROFILE" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-3-haiku-20240307-v1:0", + "created_at": null, + "display_name": "Claude 3 Haiku", + "provider": "bedrock", + "context_window": 200000, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_haiku", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 0.25, + "output_price_per_million": 1.25, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "ON_DEMAND" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-3-haiku-20240307-v1:0:200k", + "created_at": null, + "display_name": "Claude 3 Haiku", + "provider": "bedrock", + "context_window": 200000, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_haiku", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 0.25, + "output_price_per_million": 1.25, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [ + "FINE_TUNING", + "DISTILLATION" + ], + "inference_configurations": [ + "PROVISIONED" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-3-haiku-20240307-v1:0:48k", + "created_at": null, + "display_name": "Claude 3 Haiku", + "provider": "bedrock", + "context_window": 200000, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_haiku", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 0.25, + "output_price_per_million": 1.25, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "PROVISIONED" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-3-opus-20240229-v1:0", + "created_at": null, + "display_name": "Claude 3 Opus", + "provider": "bedrock", + "context_window": 200000, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_opus", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 15.0, + "output_price_per_million": 75.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "ON_DEMAND" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-3-opus-20240229-v1:0:12k", + "created_at": null, + "display_name": "Claude 3 Opus", + "provider": "bedrock", + "context_window": 200000, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_opus", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 15.0, + "output_price_per_million": 75.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "PROVISIONED" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-3-opus-20240229-v1:0:200k", + "created_at": null, + "display_name": "Claude 3 Opus", + "provider": "bedrock", + "context_window": 200000, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_opus", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 15.0, + "output_price_per_million": 75.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "PROVISIONED" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-3-opus-20240229-v1:0:28k", + "created_at": null, + "display_name": "Claude 3 Opus", + "provider": "bedrock", + "context_window": 200000, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_opus", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 15.0, + "output_price_per_million": 75.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "PROVISIONED" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-3-sonnet-20240229-v1:0", + "created_at": null, + "display_name": "Claude 3 Sonnet", + "provider": "bedrock", + "context_window": 200000, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_sonnet", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 3.0, + "output_price_per_million": 15.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "ON_DEMAND" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-3-sonnet-20240229-v1:0:200k", + "created_at": null, + "display_name": "Claude 3 Sonnet", + "provider": "bedrock", + "context_window": 200000, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_sonnet", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 3.0, + "output_price_per_million": 15.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "PROVISIONED" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-3-sonnet-20240229-v1:0:28k", + "created_at": null, + "display_name": "Claude 3 Sonnet", + "provider": "bedrock", + "context_window": 200000, + "max_tokens": 4096, + "type": "chat", + "family": "claude3_sonnet", + "supports_vision": true, + "supports_functions": true, + "supports_json_mode": true, + "input_price_per_million": 3.0, + "output_price_per_million": 15.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "PROVISIONED" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT", + "IMAGE" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-instant-v1", + "created_at": null, + "display_name": "Claude Instant", + "provider": "bedrock", + "context_window": 4096, + "max_tokens": 4096, + "type": "chat", + "family": "claude_instant", + "supports_vision": false, + "supports_functions": false, + "supports_json_mode": false, + "input_price_per_million": 0.8, + "output_price_per_million": 2.4, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "ON_DEMAND" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-instant-v1:2:100k", + "created_at": null, + "display_name": "Claude Instant", + "provider": "bedrock", + "context_window": 4096, + "max_tokens": 4096, + "type": "chat", + "family": "claude_instant", + "supports_vision": false, + "supports_functions": false, + "supports_json_mode": false, + "input_price_per_million": 0.8, + "output_price_per_million": 2.4, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "PROVISIONED" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-v2", + "created_at": null, + "display_name": "Claude", + "provider": "bedrock", + "context_window": 4096, + "max_tokens": 4096, + "type": "chat", + "family": "claude2", + "supports_vision": false, + "supports_functions": false, + "supports_json_mode": false, + "input_price_per_million": 8.0, + "output_price_per_million": 24.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "ON_DEMAND" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-v2:0:100k", + "created_at": null, + "display_name": "Claude", + "provider": "bedrock", + "context_window": 4096, + "max_tokens": 4096, + "type": "chat", + "family": "claude2", + "supports_vision": false, + "supports_functions": false, + "supports_json_mode": false, + "input_price_per_million": 8.0, + "output_price_per_million": 24.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "PROVISIONED" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-v2:0:18k", + "created_at": null, + "display_name": "Claude", + "provider": "bedrock", + "context_window": 4096, + "max_tokens": 4096, + "type": "chat", + "family": "claude2", + "supports_vision": false, + "supports_functions": false, + "supports_json_mode": false, + "input_price_per_million": 8.0, + "output_price_per_million": 24.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "PROVISIONED" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-v2:1", + "created_at": null, + "display_name": "Claude", + "provider": "bedrock", + "context_window": 4096, + "max_tokens": 4096, + "type": "chat", + "family": "claude2", + "supports_vision": false, + "supports_functions": false, + "supports_json_mode": false, + "input_price_per_million": 8.0, + "output_price_per_million": 24.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "ON_DEMAND" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-v2:1:18k", + "created_at": null, + "display_name": "Claude", + "provider": "bedrock", + "context_window": 4096, + "max_tokens": 4096, + "type": "chat", + "family": "claude2", + "supports_vision": false, + "supports_functions": false, + "supports_json_mode": false, + "input_price_per_million": 8.0, + "output_price_per_million": 24.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "PROVISIONED" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT" + ], + "output_modalities": [ + "TEXT" + ] + } + }, + { + "id": "anthropic.claude-v2:1:200k", + "created_at": null, + "display_name": "Claude", + "provider": "bedrock", + "context_window": 4096, + "max_tokens": 4096, + "type": "chat", + "family": "claude2", + "supports_vision": false, + "supports_functions": false, + "supports_json_mode": false, + "input_price_per_million": 8.0, + "output_price_per_million": 24.0, + "metadata": { + "provider_name": "Anthropic", + "customizations_supported": [], + "inference_configurations": [ + "PROVISIONED" + ], + "response_streaming_supported": true, + "input_modalities": [ + "TEXT" + ], + "output_modalities": [ + "TEXT" + ] + } + }, { "id": "aqa", "created_at": null, diff --git a/lib/ruby_llm/providers/bedrock.rb b/lib/ruby_llm/providers/bedrock.rb new file mode 100644 index 000000000..2f94bab9a --- /dev/null +++ b/lib/ruby_llm/providers/bedrock.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require 'openssl' +require 'time' + +module RubyLLM + module Providers + # AWS Bedrock API integration. Handles chat completion and streaming + # for Claude models. + module Bedrock + extend Provider + extend Bedrock::Chat + extend Bedrock::Streaming + extend Bedrock::Models + extend Bedrock::Signing + + # This provider currently only supports Anthropic models, so the tools/media implementation is shared + extend Anthropic::Media + extend Anthropic::Tools + + module_function + + def api_base + @api_base ||= "https://bedrock-runtime.#{RubyLLM.config.bedrock_region}.amazonaws.com" + end + + def post(url, payload) + signature = sign_request("#{connection.url_prefix}#{url}", payload) + connection.post url, payload do |req| + req.headers.merge! build_headers(signature.headers, streaming: block_given?) + + yield req if block_given? + end + end + + def sign_request(url, payload) + signer = create_signer + request = build_request(url, payload) + signer.sign_request(request) + end + + def create_signer + Signing::Signer.new({ + access_key_id: RubyLLM.config.bedrock_api_key, + secret_access_key: RubyLLM.config.bedrock_secret_key, + session_token: RubyLLM.config.bedrock_session_token, + region: RubyLLM.config.bedrock_region, + service: 'bedrock' + }) + end + + def build_request(url, payload) + { + connection: connection, + http_method: :post, + url: url || completion_url, + body: JSON.generate(payload, ascii_only: false) || '' + } + end + + def build_headers(signature_headers, streaming: false) + accept_header = streaming ? 'application/vnd.amazon.eventstream' : 'application/json' + + signature_headers.merge( + 'Content-Type' => 'application/json', + 'Accept' => accept_header + ) + end + + def capabilities + Bedrock::Capabilities + end + + def slug + 'bedrock' + end + + def configuration_requirements + %i[bedrock_api_key bedrock_secret_key bedrock_region] + end + end + end +end diff --git a/lib/ruby_llm/providers/bedrock/capabilities.rb b/lib/ruby_llm/providers/bedrock/capabilities.rb new file mode 100644 index 000000000..c9f91de43 --- /dev/null +++ b/lib/ruby_llm/providers/bedrock/capabilities.rb @@ -0,0 +1,168 @@ +# frozen_string_literal: true + +module RubyLLM + module Providers + module Bedrock + # Determines capabilities and pricing for AWS Bedrock models + module Capabilities + module_function + + # Returns the context window size for the given model ID + # @param model_id [String] the model identifier + # @return [Integer] the context window size in tokens + def context_window_for(model_id) + case model_id + when /anthropic\.claude-2/ then 100_000 + else 200_000 + end + end + + # Returns the maximum output tokens for the given model ID + # @param model_id [String] the model identifier + # @return [Integer] the maximum output tokens + def max_tokens_for(_model_id) + 4_096 + end + + # Returns the input price per million tokens for the given model ID + # @param model_id [String] the model identifier + # @return [Float] the price per million tokens for input + def input_price_for(model_id) + PRICES.dig(model_family(model_id), :input) || default_input_price + end + + # Returns the output price per million tokens for the given model ID + # @param model_id [String] the model identifier + # @return [Float] the price per million tokens for output + def output_price_for(model_id) + PRICES.dig(model_family(model_id), :output) || default_output_price + end + + # Determines if the model supports chat capabilities + # @param model_id [String] the model identifier + # @return [Boolean] true if the model supports chat + def supports_chat?(model_id) + model_id.match?(/anthropic\.claude/) + end + + # Determines if the model supports streaming capabilities + # @param model_id [String] the model identifier + # @return [Boolean] true if the model supports streaming + def supports_streaming?(model_id) + model_id.match?(/anthropic\.claude/) + end + + # Determines if the model supports image input/output + # @param model_id [String] the model identifier + # @return [Boolean] true if the model supports images + def supports_images?(model_id) + model_id.match?(/anthropic\.claude/) + end + + # Determines if the model supports vision capabilities + # @param model_id [String] the model identifier + # @return [Boolean] true if the model supports vision + def supports_vision?(model_id) + model_id.match?(/anthropic\.claude/) + end + + # Determines if the model supports function calling + # @param model_id [String] the model identifier + # @return [Boolean] true if the model supports functions + def supports_functions?(model_id) + model_id.match?(/anthropic\.claude/) + end + + # Determines if the model supports audio input/output + # @param model_id [String] the model identifier + # @return [Boolean] true if the model supports audio + def supports_audio?(_model_id) + false + end + + # Determines if the model supports JSON mode + # @param model_id [String] the model identifier + # @return [Boolean] true if the model supports JSON mode + def supports_json_mode?(model_id) + model_id.match?(/anthropic\.claude/) + end + + # Formats the model ID into a human-readable display name + # @param model_id [String] the model identifier + # @return [String] the formatted display name + def format_display_name(model_id) + model_id.then { |id| humanize(id) } + end + + # Determines the type of model + # @param model_id [String] the model identifier + # @return [String] the model type (chat, embedding, image, audio) + def model_type(_model_id) + 'chat' + end + + # Determines if the model supports structured output + # @param model_id [String] the model identifier + # @return [Boolean] true if the model supports structured output + def supports_structured_output?(model_id) + model_id.match?(/anthropic\.claude/) + end + + # Model family patterns for capability lookup + MODEL_FAMILIES = { + /anthropic\.claude-3-opus/ => :claude3_opus, + /anthropic\.claude-3-sonnet/ => :claude3_sonnet, + /anthropic\.claude-3-5-sonnet/ => :claude3_sonnet, + /anthropic\.claude-3-7-sonnet/ => :claude3_sonnet, + /anthropic\.claude-3-haiku/ => :claude3_haiku, + /anthropic\.claude-3-5-haiku/ => :claude3_5_haiku, + /anthropic\.claude-v2/ => :claude2, + /anthropic\.claude-instant/ => :claude_instant + }.freeze + + # Determines the model family for pricing and capability lookup + # @param model_id [String] the model identifier + # @return [Symbol] the model family identifier + def model_family(model_id) + MODEL_FAMILIES.find { |pattern, _family| model_id.match?(pattern) }&.last || :other + end + + # Pricing information for Bedrock models (per million tokens) + PRICES = { + claude3_opus: { input: 15.0, output: 75.0 }, + claude3_sonnet: { input: 3.0, output: 15.0 }, + claude3_haiku: { input: 0.25, output: 1.25 }, + claude3_5_haiku: { input: 0.8, output: 4.0 }, + claude2: { input: 8.0, output: 24.0 }, + claude_instant: { input: 0.8, output: 2.4 } + }.freeze + + # Default input price when model-specific pricing is not available + # @return [Float] the default price per million tokens + def default_input_price + 0.1 + end + + # Default output price when model-specific pricing is not available + # @return [Float] the default price per million tokens + def default_output_price + 0.2 + end + + private + + # Converts a model ID to a human-readable format + # @param id [String] the model identifier + # @return [String] the humanized model name + def humanize(id) + id.tr('-', ' ') + .split('.') + .last + .split + .map(&:capitalize) + .join(' ') + end + end + end + end +end diff --git a/lib/ruby_llm/providers/bedrock/chat.rb b/lib/ruby_llm/providers/bedrock/chat.rb new file mode 100644 index 000000000..f7786c125 --- /dev/null +++ b/lib/ruby_llm/providers/bedrock/chat.rb @@ -0,0 +1,113 @@ +# frozen_string_literal: true + +module RubyLLM + module Providers + module Bedrock + # Chat methods for the AWS Bedrock API implementation + module Chat + private + + def completion_url + "model/#{@model_id}/invoke" + end + + def render_payload(messages, tools:, temperature:, model:, stream: false) # rubocop:disable Lint/UnusedMethodArgument + # Hold model_id in instance variable for use in completion_url and stream_url + @model_id = model + case model + when /claude/ + build_claude_request(messages, tools:, temperature:, model:) + else + raise Error, nil, "Unsupported model: #{model}" + end + end + + def parse_completion_response(response) + data = response.body + content_blocks = data['content'] || [] + + text_content = extract_text_content(content_blocks) + tool_use = find_tool_use(content_blocks) + + build_message(data, text_content, tool_use) + end + + def extract_text_content(blocks) + text_blocks = blocks.select { |c| c['type'] == 'text' } + text_blocks.map { |c| c['text'] }.join + end + + def build_message(data, content, tool_use) + Message.new( + role: :assistant, + content: content, + tool_calls: parse_tool_calls(tool_use), + input_tokens: data.dig('usage', 'input_tokens'), + output_tokens: data.dig('usage', 'output_tokens'), + model_id: data['model'] + ) + end + + def build_claude_request(messages, tools:, temperature:, model:) + system_messages, chat_messages = separate_messages(messages) + system_content = build_system_content(system_messages) + + build_base_payload(chat_messages, temperature, model).tap do |payload| + add_optional_fields(payload, system_content:, tools:) + end + end + + def separate_messages(messages) + messages.partition { |msg| msg.role == :system } + end + + def build_system_content(system_messages) + system_messages.map { |msg| format_message(msg)[:content] }.join("\n\n") + end + + def build_base_payload(chat_messages, temperature, model) + { + anthropic_version: 'bedrock-2023-05-31', + messages: chat_messages.map { |msg| format_message(msg) }, + temperature: temperature, + max_tokens: max_tokens_for(model) + } + end + + def add_optional_fields(payload, system_content:, tools:) + payload[:tools] = tools.values.map { |t| function_for(t) } if tools.any? + payload[:system] = system_content unless system_content.empty? + end + + def format_message(msg) + if msg.tool_call? + format_tool_call(msg) + elsif msg.tool_result? + format_tool_result(msg) + else + format_basic_message(msg) + end + end + + def format_basic_message(msg) + { + role: convert_role(msg.role), + content: Anthropic::Media.format_content(msg.content) + } + end + + def convert_role(role) + case role + when :tool, :user then 'user' + when :system then 'system' + else 'assistant' + end + end + + def max_tokens_for(model_id) + RubyLLM.models.find(model_id)&.max_tokens + end + end + end + end +end diff --git a/lib/ruby_llm/providers/bedrock/models.rb b/lib/ruby_llm/providers/bedrock/models.rb new file mode 100644 index 000000000..9ad4cbf8b --- /dev/null +++ b/lib/ruby_llm/providers/bedrock/models.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +module RubyLLM + module Providers + module Bedrock + # Models methods for the AWS Bedrock API implementation + module Models + def list_models + @connection = nil # reset connection since base url is different + @api_base = "https://bedrock.#{RubyLLM.config.bedrock_region}.amazonaws.com" + signature = sign_request(models_url, nil) + response = connection.get(models_url) do |req| + req.headers.merge! signature.headers + end + @connection = nil # reset connection since base url is different + + parse_list_models_response(response, slug, capabilities) + end + + module_function + + def models_url + 'foundation-models' + end + + def parse_list_models_response(response, slug, capabilities) + data = response.body['modelSummaries'] || [] + data.filter { |model| model['modelId'].include?('claude') } + .map { |model| create_model_info(model, slug, capabilities) } + end + + def create_model_info(model, slug, capabilities) + model_id = model['modelId'] + ModelInfo.new( + **base_model_attributes(model_id, model, slug), + **capability_attributes(model_id, capabilities), + **pricing_attributes(model_id, capabilities), + metadata: build_metadata(model) + ) + end + + def base_model_attributes(model_id, model, slug) + { + id: model_id, + created_at: nil, + display_name: model['modelName'] || capabilities.format_display_name(model_id), + provider: slug + } + end + + def capability_attributes(model_id, capabilities) + { + context_window: capabilities.context_window_for(model_id), + max_tokens: capabilities.max_tokens_for(model_id), + type: capabilities.model_type(model_id), + family: capabilities.model_family(model_id).to_s, + supports_vision: capabilities.supports_vision?(model_id), + supports_functions: capabilities.supports_functions?(model_id), + supports_json_mode: capabilities.supports_json_mode?(model_id) + } + end + + def pricing_attributes(model_id, capabilities) + { + input_price_per_million: capabilities.input_price_for(model_id), + output_price_per_million: capabilities.output_price_for(model_id) + } + end + + def build_metadata(model) + { + provider_name: model['providerName'], + customizations_supported: model['customizationsSupported'] || [], + inference_configurations: model['inferenceTypesSupported'] || [], + response_streaming_supported: model['responseStreamingSupported'] || false, + input_modalities: model['inputModalities'] || [], + output_modalities: model['outputModalities'] || [] + } + end + end + end + end +end diff --git a/lib/ruby_llm/providers/bedrock/signing.rb b/lib/ruby_llm/providers/bedrock/signing.rb new file mode 100644 index 000000000..0dd7392ef --- /dev/null +++ b/lib/ruby_llm/providers/bedrock/signing.rb @@ -0,0 +1,831 @@ +# Portions of this file are derived from AWS SDK for Ruby (Apache License 2.0) +# Modifications made by RubyLLM in 2025 +# See THIRD_PARTY_LICENSES/AWS-SDK-NOTICE.txt for details + +# frozen_string_literal: true + +require 'openssl' +require 'tempfile' +require 'time' +require 'uri' +require 'set' +require 'cgi' +require 'pathname' + +module RubyLLM + module Providers + module Bedrock + module Signing + # Utility class for creating AWS signature version 4 signature. This class + # provides a method for generating signatures: + # + # * {#sign_request} - Computes a signature of the given request, returning + # the hash of headers that should be applied to the request. + # + # ## Configuration + # + # To use the signer, you need to specify the service, region, and credentials. + # The service name is normally the endpoint prefix to an AWS service. For + # example: + # + # ec2.us-west-1.amazonaws.com => ec2 + # + # The region is normally the second portion of the endpoint, following + # the service name. + # + # ec2.us-west-1.amazonaws.com => us-west-1 + # + # It is important to have the correct service and region name, or the + # signature will be invalid. + # + # ## Credentials + # + # The signer requires credentials. You can configure the signer + # with static credentials: + # + # signer = Aws::Sigv4::Signer.new( + # service: 's3', + # region: 'us-east-1', + # # static credentials + # access_key_id: 'akid', + # secret_access_key: 'secret' + # ) + # + # You can also provide refreshing credentials via the `:credentials_provider`. + # If you are using the AWS SDK for Ruby, you can use any of the credential + # classes: + # + # signer = Aws::Sigv4::Signer.new( + # service: 's3', + # region: 'us-east-1', + # credentials_provider: Aws::InstanceProfileCredentials.new + # ) + # + # Other AWS SDK for Ruby classes that can be provided via `:credentials_provider`: + # + # * `Aws::Credentials` + # * `Aws::SharedCredentials` + # * `Aws::InstanceProfileCredentials` + # * `Aws::AssumeRoleCredentials` + # * `Aws::ECSCredentials` + # + # A credential provider is any object that responds to `#credentials` + # returning another object that responds to `#access_key_id`, `#secret_access_key`, + # and `#session_token`. + module Errors + # Error raised when AWS credentials are missing or incomplete + class MissingCredentialsError < ArgumentError + def initialize(msg = nil) + super(msg || <<~MSG.strip) + missing credentials, provide credentials with one of the following options: + - :access_key_id and :secret_access_key + - :credentials + - :credentials_provider + MSG + end + end + + # Error raised when AWS region is not specified + class MissingRegionError < ArgumentError + def initialize(*_args) + super('missing required option :region') + end + end + end + + # Represents a signature for AWS request signing + class Signature + # @api private + def initialize(options) + options.each_pair do |attr_name, attr_value| + send("#{attr_name}=", attr_value) + end + end + + # @return [Hash] A hash of headers that should + # be applied to the HTTP request. Header keys are lower + # cased strings and may include the following: + # + # * 'host' + # * 'x-amz-date' + # * 'x-amz-security-token' + # * 'x-amz-content-sha256' + # * 'authorization' + # + attr_accessor :headers + + # @return [String] For debugging purposes. + attr_accessor :canonical_request + + # @return [String] For debugging purposes. + attr_accessor :string_to_sign + + # @return [String] For debugging purposes. + attr_accessor :content_sha256 + + # @return [String] For debugging purposes. + attr_accessor :signature + + # @return [Hash] Internal data for debugging purposes. + attr_accessor :extra + end + + # Manages AWS credentials for authentication + class Credentials + # @option options [required, String] :access_key_id + # @option options [required, String] :secret_access_key + # @option options [String, nil] :session_token (nil) + def initialize(options = {}) + if options[:access_key_id] && options[:secret_access_key] + @access_key_id = options[:access_key_id] + @secret_access_key = options[:secret_access_key] + @session_token = options[:session_token] + else + msg = 'expected both :access_key_id and :secret_access_key options' + raise ArgumentError, msg + end + end + + # @return [String] + attr_reader :access_key_id + + # @return [String] + attr_reader :secret_access_key + + # @return [String, nil] + attr_reader :session_token + + # @return [Boolean] Returns `true` if the access key id and secret + # access key are both set. + def set? + !access_key_id.nil? && + !access_key_id.empty? && + !secret_access_key.nil? && + !secret_access_key.empty? + end + end + + # Users that wish to configure static credentials can use the + # `:access_key_id` and `:secret_access_key` constructor options. + # @api private + class StaticCredentialsProvider + # @option options [Credentials] :credentials + # @option options [String] :access_key_id + # @option options [String] :secret_access_key + # @option options [String] :session_token (nil) + def initialize(options = {}) + @credentials = options[:credentials] || Credentials.new(options) + end + + # @return [Credentials] + attr_reader :credentials + + # @return [Boolean] + def set? + !!credentials && credentials.set? + end + end + + ParamComponent = Struct.new(:name, :value, :offset) + + # Utility methods for URI manipulation and hashing + module UriUtils + module_function + + def uri_escape_path(path) + path.gsub(%r{[^/]+}) { |part| uri_escape(part) } + end + + def uri_escape(string) + if string.nil? + nil + else + CGI.escape(string.encode('UTF-8')).gsub('+', '%20').gsub('%7E', '~') + end + end + + def normalize_path(uri) + normalized_path = Pathname.new(uri.path).cleanpath.to_s + # Pathname is probably not correct to use. Empty paths will + # resolve to "." and should be disregarded + normalized_path = '' if normalized_path == '.' + # Ensure trailing slashes are correctly preserved + normalized_path << '/' if uri.path.end_with?('/') && !normalized_path.end_with?('/') + uri.path = normalized_path + end + + def host(uri) + # Handles known and unknown URI schemes; default_port nil when unknown. + if uri.default_port == uri.port + uri.host + else + "#{uri.host}:#{uri.port}" + end + end + end + + # Cryptographic hash and digest utilities + module CryptoUtils + module_function + + # @param [String] value + # @return [String] + def sha256_hexdigest(value) + OpenSSL::Digest::SHA256.hexdigest(value) + end + + def hmac(key, value) + OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), key, value) + end + + def hexhmac(key, value) + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), key, value) + end + end + + # Configuration for canonical request creation + class CanonicalRequestConfig + attr_reader :uri_escape_path, :unsigned_headers + + def initialize(options = {}) + @uri_escape_path = options[:uri_escape_path] || true + @unsigned_headers = options[:unsigned_headers] || Set.new + end + end + + # Handles canonical requests for AWS signature + class CanonicalRequest + # Builds a canonical request for AWS signature + # @param [Hash] params Parameters for the canonical request + def initialize(params = {}) + @http_method = params[:http_method] + @url = params[:url] + @headers = params[:headers] + @content_sha256 = params[:content_sha256] + @config = params[:config] || CanonicalRequestConfig.new + end + + def to_s + [ + @http_method, + path, + '', # Empty string instead of normalized_querystring since we don't use query params + "#{canonical_headers}\n", + signed_headers, + @content_sha256 + ].join("\n") + end + + # Returns the list of signed headers for authorization + def signed_headers + @headers.inject([]) do |signed_headers, (header, _)| + if @config.unsigned_headers.include?(header) + signed_headers + else + signed_headers << header + end + end.sort.join(';') + end + + private + + def path + path = @url.path + path = '/' if path == '' + if @config.uri_escape_path + UriUtils.uri_escape_path(path) + else + path + end + end + + def canonical_headers + headers = @headers.inject([]) do |hdrs, (k, v)| + if @config.unsigned_headers.include?(k) + hdrs + else + hdrs << [k, v] + end + end + headers = headers.sort_by(&:first) + headers.map { |k, v| "#{k}:#{canonical_header_value(v.to_s)}" }.join("\n") + end + + def canonical_header_value(value) + value.gsub(/\s+/, ' ').strip + end + end + + # Handles signature computation + class SignatureComputation + def initialize(service, region, signing_algorithm) + @service = service + @region = region + @signing_algorithm = signing_algorithm + end + + def string_to_sign(datetime, canonical_request, algorithm) + [ + algorithm, + datetime, + credential_scope(datetime[0, 8]), + CryptoUtils.sha256_hexdigest(canonical_request) + ].join("\n") + end + + def credential_scope(date) + [ + date, + @region, + @service, + 'aws4_request' + ].join('/') + end + + def credential(credentials, date) + "#{credentials.access_key_id}/#{credential_scope(date)}" + end + + def signature(secret_access_key, date, string_to_sign) + k_date = CryptoUtils.hmac("AWS4#{secret_access_key}", date) + k_region = CryptoUtils.hmac(k_date, @region) + k_service = CryptoUtils.hmac(k_region, @service) + k_credentials = CryptoUtils.hmac(k_service, 'aws4_request') + CryptoUtils.hexhmac(k_credentials, string_to_sign) + end + end + + # Extracts and validates request components + class RequestExtractor + # Extract and process request components + # @param [Hash] request The request to process + # @param [Hash] options Options for extraction + # @return [Hash] Processed request components + def self.extract_components(request, options = {}) + normalize_path = options.fetch(:normalize_path, true) + + # Extract base components + http_method, url, headers = extract_base_components(request) + UriUtils.normalize_path(url) if normalize_path + + # Process headers and compute content SHA256 + datetime = headers['x-amz-date'] || Time.now.utc.strftime('%Y%m%dT%H%M%SZ') + content_sha256 = extract_content_sha256(headers, request[:body]) + + build_component_hash(http_method, url, headers, datetime, content_sha256) + end + + def self.build_component_hash(http_method, url, headers, datetime, content_sha256) + { + http_method: http_method, + url: url, + headers: headers, + datetime: datetime, + date: datetime[0, 8], + content_sha256: content_sha256 + } + end + + def self.extract_base_components(request) + http_method = extract_http_method(request) + url = extract_url(request) + headers = downcase_headers(request[:headers]) + [http_method, url, headers] + end + + def self.extract_content_sha256(headers, body) + headers['x-amz-content-sha256'] || CryptoUtils.sha256_hexdigest(body || '') + end + + def self.extract_http_method(request) + if request[:http_method] + request[:http_method].upcase + else + msg = 'missing required option :http_method' + raise ArgumentError, msg + end + end + + def self.extract_url(request) + if request[:url] + URI.parse(request[:url].to_s) + else + msg = 'missing required option :url' + raise ArgumentError, msg + end + end + + def self.downcase_headers(headers) + (headers || {}).to_hash.transform_keys(&:downcase) + end + end + + # Handles generating headers for AWS request signing + class HeaderBuilder + def initialize(options = {}) + @signing_algorithm = options[:signing_algorithm] + @apply_checksum_header = options[:apply_checksum_header] + @omit_session_token = options[:omit_session_token] + @region = options[:region] + end + + # Build headers for a signed request + # @param [Hash] components Request components + # @param [Credentials] creds AWS credentials + # @return [Hash] Generated headers + def build_sigv4_headers(components, creds) + headers = { + 'host' => components[:headers]['host'] || UriUtils.host(components[:url]), + 'x-amz-date' => components[:datetime] + } + + add_session_token_header(headers, creds) + add_content_sha256_header(headers, components[:content_sha256]) + + headers + end + + # Build authorization headers for a signature + # @param [Hash] sigv4_headers Headers for the signature + # @param [Hash] signature The computed signature + # @param [Hash] components Request components + # @return [Hash] Headers with authorization + def build_headers(sigv4_headers, signature, components) + headers = sigv4_headers.merge( + 'authorization' => build_authorization_header(signature) + ) + + add_omitted_session_token(headers, components[:creds]) if @omit_session_token + headers + end + + def build_authorization_header(signature) + [ + "#{signature[:algorithm]} Credential=#{signature[:credential]}", + "SignedHeaders=#{signature[:signed_headers]}", + "Signature=#{signature[:signature]}" + ].join(', ') + end + + private + + def add_session_token_header(headers, creds) + return unless creds.session_token && !@omit_session_token + + headers['x-amz-security-token'] = creds.session_token + end + + def add_content_sha256_header(headers, content_sha256) + headers['x-amz-content-sha256'] = content_sha256 if @apply_checksum_header + end + + def add_omitted_session_token(headers, creds) + return unless creds&.session_token + + headers['x-amz-security-token'] = creds.session_token + end + end + + # Credential management and fetching + class CredentialManager + def initialize(credentials_provider) + @credentials_provider = credentials_provider + end + + def fetch_credentials + credentials = @credentials_provider.credentials + if credentials_set?(credentials) + expiration = nil + expiration = @credentials_provider.expiration if @credentials_provider.respond_to?(:expiration) + [credentials, expiration] + else + raise Errors::MissingCredentialsError, + 'unable to sign request without credentials set' + end + end + + def credentials_set?(credentials) + !credentials.access_key_id.nil? && + !credentials.access_key_id.empty? && + !credentials.secret_access_key.nil? && + !credentials.secret_access_key.empty? + end + end + + # Result builder for signature computation + class SignatureResultBuilder + def initialize(signature_computation) + @signature_computation = signature_computation + end + + def build_result(request_data) + result_hash(request_data) + end + + private + + def result_hash(request_data) + { + algorithm: request_data[:algorithm], + credential: credential_from_request(request_data), + signed_headers: request_data[:canonical_request].signed_headers, + signature: request_data[:signature], + canonical_request: request_data[:creq], + string_to_sign: request_data[:sts] + } + end + + def credential_from_request(request_data) + @signature_computation.credential( + request_data[:credentials], + request_data[:date] + ) + end + end + + # Core functionality for computing signatures + class SignatureGenerator + def initialize(options = {}) + @signing_algorithm = :sigv4 # Always use sigv4 + @uri_escape_path = options[:uri_escape_path] || true + @unsigned_headers = options[:unsigned_headers] || Set.new + @service = options[:service] + @region = options[:region] + + @signature_computation = SignatureComputation.new(@service, @region, @signing_algorithm) + @result_builder = SignatureResultBuilder.new(@signature_computation) + end + + def sts_algorithm + 'AWS4-HMAC-SHA256' # Always use HMAC-SHA256 + end + + def compute_signature(components, creds, sigv4_headers) + algorithm = sts_algorithm + headers = components[:headers].merge(sigv4_headers) + + # Process request and generate signature + canonical_request = create_canonical_request(components, headers) + sig = compute_signature_from_request(canonical_request, components, creds, algorithm) + + # Build and return the final result + build_signature_result(components, creds, canonical_request, sig, algorithm) + end + + private + + def compute_signature_from_request(canonical_request, components, creds, algorithm) + creq = canonical_request.to_s + sts = generate_string_to_sign(components, creq, algorithm) + generate_signature(creds, components[:date], sts) + end + + def generate_string_to_sign(components, creq, algorithm) + @signature_computation.string_to_sign( + components[:datetime], + creq, + algorithm + ) + end + + def build_signature_result(components, creds, canonical_request, sig, algorithm) + @result_builder.build_result( + algorithm: algorithm, + credentials: creds, + date: components[:date], + signature: sig, + creq: canonical_request.to_s, + sts: generate_string_to_sign(components, canonical_request.to_s, algorithm), + canonical_request: canonical_request + ) + end + + def create_canonical_request(components, headers) + canon_req_config = create_canonical_request_config + + CanonicalRequest.new( + http_method: components[:http_method], + url: components[:url], + headers: headers, + content_sha256: components[:content_sha256], + config: canon_req_config + ) + end + + def create_canonical_request_config + CanonicalRequestConfig.new( + uri_escape_path: @uri_escape_path, + unsigned_headers: @unsigned_headers + ) + end + + def generate_signature(creds, date, string_to_sign) + @signature_computation.signature(creds.secret_access_key, date, string_to_sign) + end + end + + # Utility for extracting options and config + class SignerOptionExtractor + def self.extract_service(options) + if options[:service] + options[:service] + else + msg = 'missing required option :service' + raise ArgumentError, msg + end + end + + def self.extract_region(options) + raise Errors::MissingRegionError unless options[:region] + + options[:region] + end + + def self.extract_credentials_provider(options) + if options[:credentials_provider] + options[:credentials_provider] + elsif options.key?(:credentials) || options.key?(:access_key_id) + StaticCredentialsProvider.new(options) + else + raise Errors::MissingCredentialsError + end + end + + def self.initialize_unsigned_headers(options) + headers = Set.new(options.fetch(:unsigned_headers, []).map(&:downcase)) + headers.merge(%w[authorization x-amzn-trace-id expect]) + end + end + + # Handles initialization of Signer dependencies + class SignerInitializer + def self.create_components(options = {}) + service, region, credentials_provider = extract_core_components(options) + unsigned_headers = SignerOptionExtractor.initialize_unsigned_headers(options) + + config_options = extract_config_options(options) + + components = { + service: service, + region: region, + credentials_provider: credentials_provider, + unsigned_headers: unsigned_headers + }.merge(config_options) + + create_service_components(components) + end + + def self.extract_core_components(options) + service = SignerOptionExtractor.extract_service(options) + region = SignerOptionExtractor.extract_region(options) + credentials_provider = SignerOptionExtractor.extract_credentials_provider(options) + + [service, region, credentials_provider] + end + + def self.extract_config_options(options) + { + uri_escape_path: options.fetch(:uri_escape_path, true), + apply_checksum_header: options.fetch(:apply_checksum_header, true), + normalize_path: options.fetch(:normalize_path, true), + omit_session_token: options.fetch(:omit_session_token, false) + } + end + + def self.create_service_components(components) + signature_generator = create_signature_generator(components) + header_builder = create_header_builder(components) + credential_manager = CredentialManager.new(components[:credentials_provider]) + + components.merge( + signature_generator: signature_generator, + header_builder: header_builder, + credential_manager: credential_manager + ) + end + + def self.create_signature_generator(components) + SignatureGenerator.new( + signing_algorithm: components[:signing_algorithm], + uri_escape_path: components[:uri_escape_path], + unsigned_headers: components[:unsigned_headers], + service: components[:service], + region: components[:region] + ) + end + + def self.create_header_builder(components) + HeaderBuilder.new( + signing_algorithm: components[:signing_algorithm], + apply_checksum_header: components[:apply_checksum_header], + omit_session_token: components[:omit_session_token], + region: components[:region] + ) + end + end + + # Handles AWS request signing using SigV4 or SigV4a + class Signer + # Initialize a new signer with the provided options + # @param [Hash] options Configuration options for the signer + def initialize(options = {}) + components = SignerInitializer.create_components(options) + setup_configuration(components) + setup_service_components(components) + end + + # @return [String] + attr_reader :service + + # @return [String] + attr_reader :region + + # @return [#credentials] + attr_reader :credentials_provider + + # @return [Set] + attr_reader :unsigned_headers + + # @return [Boolean] + attr_reader :apply_checksum_header + + # Sign an AWS request with SigV4 or SigV4a + # @param [Hash] request The request to sign + # @return [Signature] The signature with headers to apply + def sign_request(request) + creds = @credential_manager.fetch_credentials.first + request_components = extract_request_components(request) + sigv4_headers = build_sigv4_headers(request_components, creds) + signature = compute_signature(request_components, creds, sigv4_headers) + build_signature_response(request_components, sigv4_headers, signature) + end + + private + + def setup_configuration(components) + @service = components[:service] + @region = components[:region] + @credentials_provider = components[:credentials_provider] + @unsigned_headers = components[:unsigned_headers] + @uri_escape_path = components[:uri_escape_path] + @apply_checksum_header = components[:apply_checksum_header] + @signing_algorithm = components[:signing_algorithm] + @normalize_path = components[:normalize_path] + @omit_session_token = components[:omit_session_token] + end + + def setup_service_components(components) + @signature_generator = components[:signature_generator] + @header_builder = components[:header_builder] + @credential_manager = components[:credential_manager] + end + + def extract_request_components(request) + RequestExtractor.extract_components( + request, + normalize_path: @normalize_path + ) + end + + def build_sigv4_headers(request_components, creds) + @header_builder.build_sigv4_headers(request_components, creds) + end + + def compute_signature(request_components, creds, sigv4_headers) + @signature_generator.compute_signature( + request_components, + creds, + sigv4_headers + ) + end + + def build_signature_response(components, sigv4_headers, signature) + headers = @header_builder.build_headers(sigv4_headers, signature, components) + + Signature.new( + headers: headers, + string_to_sign: signature[:string_to_sign], + canonical_request: signature[:canonical_request], + content_sha256: components[:content_sha256], + signature: signature[:signature] + ) + end + + class << self + def uri_escape_path(path) + UriUtils.uri_escape_path(path) + end + + def uri_escape(string) + UriUtils.uri_escape(string) + end + + def normalize_path(uri) + UriUtils.normalize_path(uri) + end + end + end + end + end + end +end diff --git a/lib/ruby_llm/providers/bedrock/streaming.rb b/lib/ruby_llm/providers/bedrock/streaming.rb new file mode 100644 index 000000000..3dad651d8 --- /dev/null +++ b/lib/ruby_llm/providers/bedrock/streaming.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require_relative 'streaming/base' +require_relative 'streaming/content_extraction' +require_relative 'streaming/message_processing' +require_relative 'streaming/payload_processing' +require_relative 'streaming/prelude_handling' + +module RubyLLM + module Providers + module Bedrock + # Streaming implementation for the AWS Bedrock API. + # This module provides functionality for handling streaming responses from AWS Bedrock, + # including message processing, content extraction, and error handling. + # + # The implementation is split into several focused modules: + # - Base: Core streaming functionality and module coordination + # - ContentExtraction: Extracting content from response data + # - MessageProcessing: Processing streaming message chunks + # - PayloadProcessing: Handling JSON payloads and chunk creation + # - PreludeHandling: Managing message preludes and headers + # + # @example Using the streaming module + # class BedrockClient + # include RubyLLM::Providers::Bedrock::Streaming + # + # def stream_response(&block) + # handle_stream(&block) + # end + # end + module Streaming + include Base + end + end + end +end diff --git a/lib/ruby_llm/providers/bedrock/streaming/base.rb b/lib/ruby_llm/providers/bedrock/streaming/base.rb new file mode 100644 index 000000000..bbf5e406b --- /dev/null +++ b/lib/ruby_llm/providers/bedrock/streaming/base.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module RubyLLM + module Providers + module Bedrock + module Streaming + # Base module for AWS Bedrock streaming functionality. + # Serves as the core module that includes all other streaming-related modules + # and provides fundamental streaming operations. + # + # Responsibilities: + # - Stream URL management + # - Stream handling and error processing + # - Coordinating the functionality of other streaming modules + # + # @example + # module MyStreamingImplementation + # include RubyLLM::Providers::Bedrock::Streaming::Base + # end + module Base + def self.included(base) + base.include ContentExtraction + base.include MessageProcessing + base.include PayloadProcessing + base.include PreludeHandling + end + + def stream_url + "model/#{@model_id}/invoke-with-response-stream" + end + + def handle_stream(&block) + buffer = String.new + proc do |chunk, _bytes, env| + if env && env.status != 200 + handle_failed_response(chunk, buffer, env) + else + process_chunk(chunk, &block) + end + end + end + end + end + end + end +end diff --git a/lib/ruby_llm/providers/bedrock/streaming/content_extraction.rb b/lib/ruby_llm/providers/bedrock/streaming/content_extraction.rb new file mode 100644 index 000000000..29dc8166e --- /dev/null +++ b/lib/ruby_llm/providers/bedrock/streaming/content_extraction.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +module RubyLLM + module Providers + module Bedrock + module Streaming + # Module for handling content extraction from AWS Bedrock streaming responses. + # Provides methods to extract and process various types of content from the response data. + # + # Responsibilities: + # - Extracting content from different response formats + # - Processing JSON deltas and content blocks + # - Extracting metadata (tokens, model IDs, tool calls) + # - Handling different content structures (arrays, blocks, completions) + module ContentExtraction + def json_delta?(data) + data['type'] == 'content_block_delta' && data.dig('delta', 'type') == 'input_json_delta' + end + + def extract_streaming_content(data) + return '' unless data.is_a?(Hash) + + extract_content_by_type(data) + end + + def extract_tool_calls(data) + data.dig('message', 'tool_calls') || data['tool_calls'] + end + + def extract_model_id(data) + data.dig('message', 'model') || @model_id + end + + def extract_input_tokens(data) + data.dig('message', 'usage', 'input_tokens') + end + + def extract_output_tokens(data) + data.dig('message', 'usage', 'output_tokens') || data.dig('usage', 'output_tokens') + end + + private + + def extract_content_by_type(data) + case data['type'] + when 'content_block_start' then extract_block_start_content(data) + when 'content_block_delta' then extract_delta_content(data) + else '' + end + end + + def extract_block_start_content(data) + data.dig('content_block', 'text').to_s + end + + def extract_delta_content(data) + data.dig('delta', 'text').to_s + end + end + end + end + end +end diff --git a/lib/ruby_llm/providers/bedrock/streaming/message_processing.rb b/lib/ruby_llm/providers/bedrock/streaming/message_processing.rb new file mode 100644 index 000000000..a43864eb1 --- /dev/null +++ b/lib/ruby_llm/providers/bedrock/streaming/message_processing.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: true + +module RubyLLM + module Providers + module Bedrock + module Streaming + # Module for processing streaming messages from AWS Bedrock. + # Handles the core message processing logic, including validation and chunking. + # + # Responsibilities: + # - Processing incoming message chunks + # - Validating message structure and content + # - Managing message offsets and boundaries + # - Error handling during message processing + # + # @example Processing a message chunk + # offset = process_message(chunk, current_offset) do |processed_chunk| + # handle_processed_chunk(processed_chunk) + # end + module MessageProcessing + def process_chunk(chunk, &) + offset = 0 + offset = process_message(chunk, offset, &) while offset < chunk.bytesize + rescue StandardError => e + RubyLLM.logger.debug "Error processing chunk: #{e.message}" + RubyLLM.logger.debug "Chunk size: #{chunk.bytesize}" + end + + def process_message(chunk, offset, &) + return chunk.bytesize unless can_read_prelude?(chunk, offset) + + message_info = extract_message_info(chunk, offset) + return find_next_message(chunk, offset) unless message_info + + process_valid_message(chunk, offset, message_info, &) + end + + def process_valid_message(chunk, offset, message_info, &) + payload = extract_payload(chunk, message_info[:headers_end], message_info[:payload_end]) + return find_next_message(chunk, offset) unless valid_payload?(payload) + + process_payload(payload, &) + offset + message_info[:total_length] + end + + private + + def extract_message_info(chunk, offset) + total_length, headers_length = read_prelude(chunk, offset) + return unless valid_lengths?(total_length, headers_length) + + message_end = offset + total_length + return unless chunk.bytesize >= message_end + + headers_end, payload_end = calculate_positions(offset, total_length, headers_length) + return unless valid_positions?(headers_end, payload_end, chunk.bytesize) + + { total_length:, headers_length:, headers_end:, payload_end: } + end + + def extract_payload(chunk, headers_end, payload_end) + chunk[headers_end...payload_end] + end + + def valid_payload?(payload) + return false if payload.nil? || payload.empty? + + json_start = payload.index('{') + json_end = payload.rindex('}') + + return false if json_start.nil? || json_end.nil? || json_start >= json_end + + true + end + end + end + end + end +end diff --git a/lib/ruby_llm/providers/bedrock/streaming/payload_processing.rb b/lib/ruby_llm/providers/bedrock/streaming/payload_processing.rb new file mode 100644 index 000000000..2b7153286 --- /dev/null +++ b/lib/ruby_llm/providers/bedrock/streaming/payload_processing.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +require 'base64' + +module RubyLLM + module Providers + module Bedrock + module Streaming + # Module for processing payloads from AWS Bedrock streaming responses. + # Handles JSON payload extraction, decoding, and chunk creation. + # + # Responsibilities: + # - Extracting and validating JSON payloads + # - Decoding Base64-encoded response data + # - Creating response chunks from processed data + # - Error handling for JSON parsing and processing + # + # @example Processing a payload + # process_payload(raw_payload) do |chunk| + # yield_chunk_to_client(chunk) + # end + module PayloadProcessing + def process_payload(payload, &) + json_payload = extract_json_payload(payload) + parse_and_process_json(json_payload, &) + rescue JSON::ParserError => e + log_json_parse_error(e, json_payload) + rescue StandardError => e + log_general_error(e) + end + + private + + def extract_json_payload(payload) + json_start = payload.index('{') + json_end = payload.rindex('}') + payload[json_start..json_end] + end + + def parse_and_process_json(json_payload, &) + json_data = JSON.parse(json_payload) + process_json_data(json_data, &) + end + + def process_json_data(json_data, &) + return unless json_data['bytes'] + + data = decode_and_parse_data(json_data) + create_and_yield_chunk(data, &) + end + + def decode_and_parse_data(json_data) + decoded_bytes = Base64.strict_decode64(json_data['bytes']) + JSON.parse(decoded_bytes) + end + + def create_and_yield_chunk(data, &block) + block.call(build_chunk(data)) + end + + def build_chunk(data) + Chunk.new( + **extract_chunk_attributes(data) + ) + end + + def extract_chunk_attributes(data) + { + role: :assistant, + model_id: extract_model_id(data), + content: extract_streaming_content(data), + input_tokens: extract_input_tokens(data), + output_tokens: extract_output_tokens(data), + tool_calls: extract_tool_calls(data) + } + end + + def log_json_parse_error(error, json_payload) + RubyLLM.logger.debug "Failed to parse payload as JSON: #{error.message}" + RubyLLM.logger.debug "Attempted JSON payload: #{json_payload.inspect}" + end + + def log_general_error(error) + RubyLLM.logger.debug "Error processing payload: #{error.message}" + end + end + end + end + end +end diff --git a/lib/ruby_llm/providers/bedrock/streaming/prelude_handling.rb b/lib/ruby_llm/providers/bedrock/streaming/prelude_handling.rb new file mode 100644 index 000000000..920d94702 --- /dev/null +++ b/lib/ruby_llm/providers/bedrock/streaming/prelude_handling.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true + +module RubyLLM + module Providers + module Bedrock + module Streaming + # Module for handling message preludes in AWS Bedrock streaming responses. + # Manages the parsing and validation of message headers and prelude data. + # + # Responsibilities: + # - Reading and validating message preludes + # - Calculating message positions and boundaries + # - Finding and validating prelude positions in chunks + # - Ensuring message integrity through length validation + # + # @example Reading a prelude + # if can_read_prelude?(chunk, offset) + # total_length, headers_length = read_prelude(chunk, offset) + # process_message_with_lengths(total_length, headers_length) + # end + module PreludeHandling + def can_read_prelude?(chunk, offset) + chunk.bytesize - offset >= 12 + end + + def read_prelude(chunk, offset) + total_length = chunk[offset...offset + 4].unpack1('N') + headers_length = chunk[offset + 4...offset + 8].unpack1('N') + [total_length, headers_length] + end + + def valid_lengths?(total_length, headers_length) + validate_length_constraints(total_length, headers_length) + end + + def calculate_positions(offset, total_length, headers_length) + headers_end = offset + 12 + headers_length + payload_end = offset + total_length - 4 # Subtract 4 bytes for message CRC + [headers_end, payload_end] + end + + def valid_positions?(headers_end, payload_end, chunk_size) + return false if headers_end >= payload_end + return false if headers_end >= chunk_size + return false if payload_end > chunk_size + + true + end + + def find_next_message(chunk, offset) + next_prelude = find_next_prelude(chunk, offset + 4) + next_prelude || chunk.bytesize + end + + def find_next_prelude(chunk, start_offset) + scan_range(chunk, start_offset).each do |pos| + return pos if valid_prelude_at_position?(chunk, pos) + end + nil + end + + private + + def scan_range(chunk, start_offset) + (start_offset...(chunk.bytesize - 8)) + end + + def valid_prelude_at_position?(chunk, pos) + lengths = extract_potential_lengths(chunk, pos) + validate_length_constraints(*lengths) + end + + def extract_potential_lengths(chunk, pos) + [ + chunk[pos...pos + 4].unpack1('N'), + chunk[pos + 4...pos + 8].unpack1('N') + ] + end + + def validate_length_constraints(total_length, headers_length) + return false if total_length.nil? || headers_length.nil? + return false if total_length <= 0 || total_length > 1_000_000 + return false if headers_length <= 0 || headers_length >= total_length + + true + end + end + end + end + end +end diff --git a/lib/tasks/model_updater.rb b/lib/tasks/model_updater.rb index a87f97df1..7685a2191 100644 --- a/lib/tasks/model_updater.rb +++ b/lib/tasks/model_updater.rb @@ -14,15 +14,23 @@ def run private def configure_from_env - RubyLLM.configure do |c| - c.openai_api_key = ENV.fetch('OPENAI_API_KEY', nil) - c.anthropic_api_key = ENV.fetch('ANTHROPIC_API_KEY', nil) - c.gemini_api_key = ENV.fetch('GEMINI_API_KEY', nil) - c.deepseek_api_key = ENV.fetch('DEEPSEEK_API_KEY', nil) - c.request_timeout = 30 + RubyLLM.configure do |config| + config.openai_api_key = ENV.fetch('OPENAI_API_KEY', nil) + config.anthropic_api_key = ENV.fetch('ANTHROPIC_API_KEY', nil) + config.gemini_api_key = ENV.fetch('GEMINI_API_KEY', nil) + config.deepseek_api_key = ENV.fetch('DEEPSEEK_API_KEY', nil) + configure_bedrock(config) + config.request_timeout = 30 end end + def configure_bedrock(config) + config.bedrock_api_key = ENV.fetch('AWS_ACCESS_KEY_ID', nil) + config.bedrock_secret_key = ENV.fetch('AWS_SECRET_ACCESS_KEY', nil) + config.bedrock_region = ENV.fetch('AWS_REGION', nil) + config.bedrock_session_token = ENV.fetch('AWS_SESSION_TOKEN', nil) + end + def refresh_models # rubocop:disable Metrics/AbcSize,Metrics/MethodLength initial_count = RubyLLM.models.all.size puts "Refreshing models (#{initial_count} cached)..." diff --git a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_claude-3-5-haiku_can_handle_multi-turn_conversations_with_bedrock.yml b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_claude-3-5-haiku_can_handle_multi-turn_conversations_with_bedrock.yml new file mode 100644 index 000000000..01769fccc --- /dev/null +++ b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_claude-3-5-haiku_can_handle_multi-turn_conversations_with_bedrock.yml @@ -0,0 +1,120 @@ +--- +http_interactions: +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"Who + was Ruby''s creator?"}],"temperature":0.7,"max_tokens":4096}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250325T222413Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - 45bc07e92f3e4928655fb657829c1790fcb1594aafa5abfd051050018ced0ffe + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250325/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=2e0f1b029bf5d0ceab9c70d16e04ab18f92f86a7148e7771f81b35959fe9613d + Content-Type: + - application/json + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 25 Mar 2025 22:23:35 GMT + Content-Type: + - application/json + Content-Length: + - '583' + Connection: + - keep-alive + X-Amzn-Requestid: + - 747f0c38-c89c-4041-8527-984920f9e9ae + X-Amzn-Bedrock-Invocation-Latency: + - '2790' + X-Amzn-Bedrock-Output-Token-Count: + - '77' + X-Amzn-Bedrock-Input-Token-Count: + - '13' + body: + encoding: UTF-8 + string: '{"id":"msg_bdrk_01C5ZuowJFSpehKK5jvJ2tEA","type":"message","role":"assistant","model":"claude-3-5-haiku-20241022","content":[{"type":"text","text":"Ruby + was created by Yukihiro Matsumoto (often called \"Matz\") in Japan. He first + released Ruby in 1995, designing it to be a programming language that prioritizes + human productivity and programmer happiness. Matz wanted to create a language + that was more natural and enjoyable to use compared to other programming languages + of that time."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":13,"output_tokens":77}}' + recorded_at: Tue, 25 Mar 2025 22:24:16 GMT +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"Who + was Ruby''s creator?"},{"role":"assistant","content":"Ruby was created by + Yukihiro Matsumoto (often called \"Matz\") in Japan. He first released Ruby + in 1995, designing it to be a programming language that prioritizes human + productivity and programmer happiness. Matz wanted to create a language that + was more natural and enjoyable to use compared to other programming languages + of that time."},{"role":"user","content":"What year did he create Ruby?"}],"temperature":0.7,"max_tokens":4096}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250325T222416Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - 474b86ca5c9de2f96dfc3faafd2c86535b93b25d30ab62cc053e3f1ba0b92df2 + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250325/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=d86a5908714b7a1faf95628bcfea98883e77b494e20afdb21e6ffd6d0a9d11ad + Content-Type: + - application/json + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 25 Mar 2025 22:23:36 GMT + Content-Type: + - application/json + Content-Length: + - '411' + Connection: + - keep-alive + X-Amzn-Requestid: + - 16de93f7-0a1c-433f-be10-77c8d1bdae48 + X-Amzn-Bedrock-Invocation-Latency: + - '1143' + X-Amzn-Bedrock-Output-Token-Count: + - '49' + X-Amzn-Bedrock-Input-Token-Count: + - '100' + body: + encoding: UTF-8 + string: '{"id":"msg_bdrk_01QxrkK4Jn5mBeVvowN9pD7g","type":"message","role":"assistant","model":"claude-3-5-haiku-20241022","content":[{"type":"text","text":"Yukihiro + Matsumoto first released Ruby in 1995. Specifically, he publicly released + Ruby version 0.95 in December of that year, making 1995 the year Ruby was + created."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":100,"output_tokens":49}}' + recorded_at: Tue, 25 Mar 2025 22:24:17 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_claude-3-5-haiku_can_handle_system_messages_with_bedrock.yml b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_claude-3-5-haiku_can_handle_system_messages_with_bedrock.yml new file mode 100644 index 000000000..ac118ae79 --- /dev/null +++ b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_claude-3-5-haiku_can_handle_system_messages_with_bedrock.yml @@ -0,0 +1,121 @@ +--- +http_interactions: +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"What + is 15 + 27?"}],"temperature":0.7,"max_tokens":4096,"system":"You are a helpful + math tutor who always shows your work."}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250331T211814Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - fbe47914c1da712b79e70a557d3f0b86f91d283f7c2e07643feff6580105f319 + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250331/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=d8e79c8ca7d9a7a14c0bb83d654a729530d80426c1d55860f839174e123ee24f + Content-Type: + - application/json + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 31 Mar 2025 21:17:35 GMT + Content-Type: + - application/json + Content-Length: + - '618' + Connection: + - keep-alive + X-Amzn-Requestid: + - 5e07f27e-93dd-4c55-a1b0-67c6a3884627 + X-Amzn-Bedrock-Invocation-Latency: + - '2573' + X-Amzn-Bedrock-Output-Token-Count: + - '123' + X-Amzn-Bedrock-Input-Token-Count: + - '29' + body: + encoding: UTF-8 + string: '{"id":"msg_bdrk_01BwYUhrKeru4SJ2Djr6e3V2","type":"message","role":"assistant","model":"claude-3-5-haiku-20241022","content":[{"type":"text","text":"Let + me solve this step by step:\n\n 15\n+ 27\n-----\n 42\n\nI''ll break down + the addition:\n1. First, add the ones column: 5 + 7 = 12\n2. Write down the + 2 in the ones place and carry the 1 to the tens column\n3. In the tens column, + add 1 (carried over) + 1 + 2 = 4\n4. The final answer is 42\n\nSo, 15 + 27 + = 42"}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":29,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":123}}' + recorded_at: Mon, 31 Mar 2025 21:18:17 GMT +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"What + is 15 + 27?"},{"role":"assistant","content":"Let me solve this step by step:\n\n 15\n+ + 27\n-----\n 42\n\nI''ll break down the addition:\n1. First, add the ones + column: 5 + 7 = 12\n2. Write down the 2 in the ones place and carry the 1 + to the tens column\n3. In the tens column, add 1 (carried over) + 1 + 2 = + 4\n4. The final answer is 42\n\nSo, 15 + 27 = 42"},{"role":"user","content":"What + is 25 * 4?"}],"temperature":0.7,"max_tokens":4096,"system":"You are a helpful + math tutor who always shows your work.\n\nAlways include a fun fact about + numbers in your response."}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250331T211817Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - a55ae236e70cacb5532c4a120209c0280ff759a285b5a875caafb5a942a086a4 + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250331/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=7ab569ddd72b52f7f4b253113a05cb0e00d5f111eb53846bc3effd93ce958a6f + Content-Type: + - application/json + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 31 Mar 2025 21:17:38 GMT + Content-Type: + - application/json + Content-Length: + - '773' + Connection: + - keep-alive + X-Amzn-Requestid: + - 5ca42b45-0c6c-474b-9f37-2b76a8dcc89c + X-Amzn-Bedrock-Invocation-Latency: + - '3047' + X-Amzn-Bedrock-Output-Token-Count: + - '159' + X-Amzn-Bedrock-Input-Token-Count: + - '176' + body: + encoding: ASCII-8BIT + string: !binary |- + eyJpZCI6Im1zZ19iZHJrXzAxTXpxcnNkcmF5anJZSnRDcW9RNDRleiIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsIm1vZGVsIjoiY2xhdWRlLTMtNS1oYWlrdS0yMDI0MTAyMiIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IkxldCBtZSBzb2x2ZSB0aGlzIHN0ZXAgYnkgc3RlcDpcblxuICAgIDI1XG7DlyAgICA0XG4tLS0tLS0tXG4gICAxMDBcblxuSGVyZSdzIHRoZSBtdWx0aXBsaWNhdGlvbiBicmVha2Rvd246XG4xLiBNdWx0aXBseSA1IMOXIDQgPSAyMCwgd3JpdGUgZG93biAwLCBjYXJyeSB0aGUgMlxuMi4gTXVsdGlwbHkgMiDDlyA0ID0gOCwgdGhlbiBhZGQgdGhlIGNhcnJpZWQgMlxuMy4gU28gOCArIDIgPSAxMFxuNC4gVGhlIGZpbmFsIGFuc3dlciBpcyAxMDBcblxuU28sIDI1IMOXIDQgPSAxMDBcblxuRnVuIE51bWJlciBGYWN0OiBEaWQgeW91IGtub3cgdGhhdCAxMDAgaXMgY29uc2lkZXJlZCBhIFwicGVyZmVjdCBzcXVhcmVcIiBiZWNhdXNlIGl0J3MgdGhlIHJlc3VsdCBvZiAxMCDDlyAxMD8gUGVyZmVjdCBzcXVhcmVzIGhhdmUgd2hvbGUgbnVtYmVyIHJvb3RzIHRoYXQgbXVsdGlwbHkgZXZlbmx5IGludG8gdGhlbXNlbHZlcyEifV0sInN0b3BfcmVhc29uIjoiZW5kX3R1cm4iLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjE3NiwiY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zIjowLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyI6MCwib3V0cHV0X3Rva2VucyI6MTU5fX0= + recorded_at: Mon, 31 Mar 2025 21:18:20 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_claude-3-5-haiku_can_have_a_basic_conversation_with_bedrock.yml b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_claude-3-5-haiku_can_have_a_basic_conversation_with_bedrock.yml new file mode 100644 index 000000000..8179ddd2b --- /dev/null +++ b/spec/fixtures/vcr_cassettes/chat_basic_chat_functionality_claude-3-5-haiku_can_have_a_basic_conversation_with_bedrock.yml @@ -0,0 +1,55 @@ +--- +http_interactions: +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"What''s + 2 + 2?"}],"temperature":0.7,"max_tokens":4096}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250325T222412Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - b5957298a88788e861cf24c2faff82644662c726eed2de6599a41f3789caa703 + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250325/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=2223548f016c41afc671c3964098931aeb2d9ca07b3a18c13402c5289f4a7aa9 + Content-Type: + - application/json + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 25 Mar 2025 22:23:32 GMT + Content-Type: + - application/json + Content-Length: + - '245' + Connection: + - keep-alive + X-Amzn-Requestid: + - 186ac8b6-6234-45f8-8b4c-c893e78a949d + X-Amzn-Bedrock-Invocation-Latency: + - '946' + X-Amzn-Bedrock-Output-Token-Count: + - '5' + X-Amzn-Bedrock-Input-Token-Count: + - '16' + body: + encoding: UTF-8 + string: '{"id":"msg_bdrk_018iG3YNksavaUeLbt48zRrB","type":"message","role":"assistant","model":"claude-3-5-haiku-20241022","content":[{"type":"text","text":"4"}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":16,"output_tokens":5}}' + recorded_at: Tue, 25 Mar 2025 22:24:13 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_function_calling_claude-3-5-haiku_can_use_tools_in_multi-turn_conversations_with_bedrock.yml b/spec/fixtures/vcr_cassettes/chat_function_calling_claude-3-5-haiku_can_use_tools_in_multi-turn_conversations_with_bedrock.yml new file mode 100644 index 000000000..c8a31a137 --- /dev/null +++ b/spec/fixtures/vcr_cassettes/chat_function_calling_claude-3-5-haiku_can_use_tools_in_multi-turn_conversations_with_bedrock.yml @@ -0,0 +1,245 @@ +--- +http_interactions: +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)"}],"temperature":0.7,"max_tokens":4096,"tools":[{"name":"weather","description":"Gets + current weather for a location","input_schema":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250325T222238Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - 175fe07b52825d214f2938f4dcfb11a1099924121ee86d46d6b027b10fa92fa4 + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250325/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=34d98b1daf7e73fed2dfec76ff790ee8db4cdbe70bbba364e32721b52446233a + Content-Type: + - application/json + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 25 Mar 2025 22:21:58 GMT + Content-Type: + - application/json + Content-Length: + - '460' + Connection: + - keep-alive + X-Amzn-Requestid: + - ca2ada88-c8d1-46ab-8a2d-eb1e6c3868dc + X-Amzn-Bedrock-Invocation-Latency: + - '1709' + X-Amzn-Bedrock-Output-Token-Count: + - '90' + X-Amzn-Bedrock-Input-Token-Count: + - '389' + body: + encoding: UTF-8 + string: '{"id":"msg_bdrk_01AheF11cFX5N1bR8XeJD7qj","type":"message","role":"assistant","model":"claude-3-5-haiku-20241022","content":[{"type":"text","text":"I''ll + help you check the current weather in Berlin using the provided coordinates."},{"type":"tool_use","id":"toolu_bdrk_01RjqxekiaA5DWYzAHaxdL2m","name":"weather","input":{"latitude":"52.5200","longitude":"13.4050"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":389,"output_tokens":90}}' + recorded_at: Tue, 25 Mar 2025 22:22:40 GMT +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)"},{"role":"assistant","content":[{"type":"text","text":"I''ll + help you check the current weather in Berlin using the provided coordinates."},{"type":"tool_use","id":"toolu_bdrk_01RjqxekiaA5DWYzAHaxdL2m","name":"weather","input":{"latitude":"52.5200","longitude":"13.4050"}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_01RjqxekiaA5DWYzAHaxdL2m","content":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h"}]}],"temperature":0.7,"max_tokens":4096,"tools":[{"name":"weather","description":"Gets + current weather for a location","input_schema":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250325T222240Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - 617b7969b05cf69b588756ce435959ced5b8a73c9c075762eb0a24b2c60a5253 + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250325/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=543d20b349fd60ff4b8506070cdc500d472b804705630d8b20460cdbc235c9d0 + Content-Type: + - application/json + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 25 Mar 2025 22:22:01 GMT + Content-Type: + - application/json + Content-Length: + - '558' + Connection: + - keep-alive + X-Amzn-Requestid: + - 424dc6e1-3c02-4310-8858-95b20fc10390 + X-Amzn-Bedrock-Invocation-Latency: + - '2392' + X-Amzn-Bedrock-Output-Token-Count: + - '79' + X-Amzn-Bedrock-Input-Token-Count: + - '518' + body: + encoding: ASCII-8BIT + string: !binary |- + eyJpZCI6Im1zZ19iZHJrXzAxM2JIc2lKVTg0UGh4NTg4SHp6YXRQZyIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsIm1vZGVsIjoiY2xhdWRlLTMtNS1oYWlrdS0yMDI0MTAyMiIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IkJhc2VkIG9uIHRoZSB3ZWF0aGVyIGluZm9ybWF0aW9uLCBoZXJlJ3MgdGhlIGN1cnJlbnQgd2VhdGhlciBpbiBCZXJsaW46XG4tIFRlbXBlcmF0dXJlOiAxNcKwQyAoNTnCsEYpXG4tIFdpbmQgU3BlZWQ6IDEwIGttL2hcblxuSXQgc2VlbXMgbGlrZSBhIG1pbGQgZGF5IGluIEJlcmxpbiB3aXRoIGEgbW9kZXJhdGUgYnJlZXplLiBUaGUgdGVtcGVyYXR1cmUgaXMgY29tZm9ydGFibGUsIHBlcmZlY3QgZm9yIGxpZ2h0IG91dGRvb3IgYWN0aXZpdGllcy4gV291bGQgeW91IGxpa2UgdG8ga25vdyBhbnl0aGluZyBlbHNlIGFib3V0IHRoZSB3ZWF0aGVyPyJ9XSwic3RvcF9yZWFzb24iOiJlbmRfdHVybiIsInN0b3Bfc2VxdWVuY2UiOm51bGwsInVzYWdlIjp7ImlucHV0X3Rva2VucyI6NTE4LCJvdXRwdXRfdG9rZW5zIjo3OX19 + recorded_at: Tue, 25 Mar 2025 22:22:42 GMT +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)"},{"role":"assistant","content":[{"type":"text","text":"I''ll + help you check the current weather in Berlin using the provided coordinates."},{"type":"tool_use","id":"toolu_bdrk_01RjqxekiaA5DWYzAHaxdL2m","name":"weather","input":{"latitude":"52.5200","longitude":"13.4050"}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_01RjqxekiaA5DWYzAHaxdL2m","content":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h"}]},{"role":"assistant","content":"Based + on the weather information, here''s the current weather in Berlin:\n- Temperature: + 15°C (59°F)\n- Wind Speed: 10 km/h\n\nIt seems like a mild day in Berlin with + a moderate breeze. The temperature is comfortable, perfect for light outdoor + activities. Would you like to know anything else about the weather?"},{"role":"user","content":"What''s + the weather in Paris? (48.8575, 2.3514)"}],"temperature":0.7,"max_tokens":4096,"tools":[{"name":"weather","description":"Gets + current weather for a location","input_schema":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250325T222242Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - c96f336256d9638968fb74b20338a6f8437c6065e81907ce6344384541430ce9 + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250325/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=27ede3aea3e719588d13ac055d6b9bb1071a83bc0e6e7e2a8a64444966d2ee50 + Content-Type: + - application/json + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 25 Mar 2025 22:22:02 GMT + Content-Type: + - application/json + Content-Length: + - '465' + Connection: + - keep-alive + X-Amzn-Requestid: + - 8db67aae-dfc5-4594-86fa-a1e83ddcb2e7 + X-Amzn-Bedrock-Invocation-Latency: + - '1338' + X-Amzn-Bedrock-Output-Token-Count: + - '89' + X-Amzn-Bedrock-Input-Token-Count: + - '619' + body: + encoding: UTF-8 + string: '{"id":"msg_bdrk_0184kfx1R6kc44pc5K8FGVTX","type":"message","role":"assistant","model":"claude-3-5-haiku-20241022","content":[{"type":"text","text":"I''ll + retrieve the current weather information for Paris using the provided coordinates."},{"type":"tool_use","id":"toolu_bdrk_018WvqrpbvkYWcXZ8BbicqK2","name":"weather","input":{"latitude":"48.8575","longitude":"2.3514"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":619,"output_tokens":89}}' + recorded_at: Tue, 25 Mar 2025 22:22:44 GMT +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)"},{"role":"assistant","content":[{"type":"text","text":"I''ll + help you check the current weather in Berlin using the provided coordinates."},{"type":"tool_use","id":"toolu_bdrk_01RjqxekiaA5DWYzAHaxdL2m","name":"weather","input":{"latitude":"52.5200","longitude":"13.4050"}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_01RjqxekiaA5DWYzAHaxdL2m","content":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h"}]},{"role":"assistant","content":"Based + on the weather information, here''s the current weather in Berlin:\n- Temperature: + 15°C (59°F)\n- Wind Speed: 10 km/h\n\nIt seems like a mild day in Berlin with + a moderate breeze. The temperature is comfortable, perfect for light outdoor + activities. Would you like to know anything else about the weather?"},{"role":"user","content":"What''s + the weather in Paris? (48.8575, 2.3514)"},{"role":"assistant","content":[{"type":"text","text":"I''ll + retrieve the current weather information for Paris using the provided coordinates."},{"type":"tool_use","id":"toolu_bdrk_018WvqrpbvkYWcXZ8BbicqK2","name":"weather","input":{"latitude":"48.8575","longitude":"2.3514"}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_018WvqrpbvkYWcXZ8BbicqK2","content":"Current + weather at 48.8575, 2.3514: 15°C, Wind: 10 km/h"}]}],"temperature":0.7,"max_tokens":4096,"tools":[{"name":"weather","description":"Gets + current weather for a location","input_schema":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250325T222244Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - c4e15659416061fb996a331cbf4318dbf3dfaf53a241eed16e620bbeb12c30ce + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250325/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=e577db0e44c13043ac927ea038d5e25515010a3bb50f2158b8f4b59d570cb32f + Content-Type: + - application/json + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 25 Mar 2025 22:22:05 GMT + Content-Type: + - application/json + Content-Length: + - '602' + Connection: + - keep-alive + X-Amzn-Requestid: + - c52cad00-c97a-42e7-b601-e3c8e9c21c76 + X-Amzn-Bedrock-Invocation-Latency: + - '2293' + X-Amzn-Bedrock-Output-Token-Count: + - '93' + X-Amzn-Bedrock-Input-Token-Count: + - '747' + body: + encoding: ASCII-8BIT + string: !binary |- + eyJpZCI6Im1zZ19iZHJrXzAxOXFremVnaW50ZW1zNnBzNEJBNllXeiIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsIm1vZGVsIjoiY2xhdWRlLTMtNS1oYWlrdS0yMDI0MTAyMiIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IkhlcmUncyB0aGUgY3VycmVudCB3ZWF0aGVyIGluIFBhcmlzOlxuLSBUZW1wZXJhdHVyZTogMTXCsEMgKDU5wrBGKVxuLSBXaW5kIFNwZWVkOiAxMCBrbS9oXG5cbkludGVyZXN0aW5nbHksIHRoZSB3ZWF0aGVyIGluIFBhcmlzIGlzIHF1aXRlIHNpbWlsYXIgdG8gQmVybGluIGF0IHRoZSBtb21lbnQsIHdpdGggdGhlIHNhbWUgdGVtcGVyYXR1cmUgYW5kIHdpbmQgc3BlZWQuIEl0J3MgYSBtaWxkIGRheSB0aGF0IHNob3VsZCBiZSBwbGVhc2FudCBmb3Igd2Fsa2luZyBhcm91bmQgYW5kIGV4cGxvcmluZyB0aGUgY2l0eS4gSXMgdGhlcmUgYW55dGhpbmcgZWxzZSB5b3UnZCBsaWtlIHRvIGtub3cgYWJvdXQgdGhlIHdlYXRoZXI/In1dLCJzdG9wX3JlYXNvbiI6ImVuZF90dXJuIiwic3RvcF9zZXF1ZW5jZSI6bnVsbCwidXNhZ2UiOnsiaW5wdXRfdG9rZW5zIjo3NDcsIm91dHB1dF90b2tlbnMiOjkzfX0= + recorded_at: Tue, 25 Mar 2025 22:22:46 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_function_calling_claude-3-5-haiku_can_use_tools_with_bedrock.yml b/spec/fixtures/vcr_cassettes/chat_function_calling_claude-3-5-haiku_can_use_tools_with_bedrock.yml new file mode 100644 index 000000000..37a0c4049 --- /dev/null +++ b/spec/fixtures/vcr_cassettes/chat_function_calling_claude-3-5-haiku_can_use_tools_with_bedrock.yml @@ -0,0 +1,117 @@ +--- +http_interactions: +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)"}],"temperature":0.7,"max_tokens":4096,"tools":[{"name":"weather","description":"Gets + current weather for a location","input_schema":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250325T214315Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - 175fe07b52825d214f2938f4dcfb11a1099924121ee86d46d6b027b10fa92fa4 + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250325/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=b4a8925c3fad30e1dc39636ad2378fa02662aa8bc1567778c04bed77b1ec510b + Content-Type: + - application/json + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 25 Mar 2025 21:42:36 GMT + Content-Type: + - application/json + Content-Length: + - '465' + Connection: + - keep-alive + X-Amzn-Requestid: + - e3bd8814-37bc-4a6f-82ac-b2d062d34147 + X-Amzn-Bedrock-Invocation-Latency: + - '1800' + X-Amzn-Bedrock-Output-Token-Count: + - '91' + X-Amzn-Bedrock-Input-Token-Count: + - '389' + body: + encoding: UTF-8 + string: '{"id":"msg_bdrk_01Ne8yKo4hhdGv3xkVzDN5fP","type":"message","role":"assistant","model":"claude-3-5-haiku-20241022","content":[{"type":"text","text":"Let + me check the current weather in Berlin for you using the coordinates you provided."},{"type":"tool_use","id":"toolu_bdrk_0154fPJkniARCyGTTWHgN2CV","name":"weather","input":{"latitude":"52.5200","longitude":"13.4050"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":389,"output_tokens":91}}' + recorded_at: Tue, 25 Mar 2025 21:43:17 GMT +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)"},{"role":"assistant","content":[{"type":"text","text":"Let + me check the current weather in Berlin for you using the coordinates you provided."},{"type":"tool_use","id":"toolu_bdrk_0154fPJkniARCyGTTWHgN2CV","name":"weather","input":{"latitude":"52.5200","longitude":"13.4050"}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_0154fPJkniARCyGTTWHgN2CV","content":"Current + weather at 52.5200, 13.4050: 15°C, Wind: 10 km/h"}]}],"temperature":0.7,"max_tokens":4096,"tools":[{"name":"weather","description":"Gets + current weather for a location","input_schema":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250325T214317Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - cff2e059af1693e25b684a93f8bc18a8e8615af89575672e62308129a2a0789a + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250325/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=4c8bebcd9cd21115855985fc879fcfca2108d3f65fb0e444ad23bbe06a67942c + Content-Type: + - application/json + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 25 Mar 2025 21:42:38 GMT + Content-Type: + - application/json + Content-Length: + - '529' + Connection: + - keep-alive + X-Amzn-Requestid: + - 4cd943ef-539f-4698-9a0a-2e0afa0528dc + X-Amzn-Bedrock-Invocation-Latency: + - '2504' + X-Amzn-Bedrock-Output-Token-Count: + - '73' + X-Amzn-Bedrock-Input-Token-Count: + - '519' + body: + encoding: ASCII-8BIT + string: !binary |- + eyJpZCI6Im1zZ19iZHJrXzAxMmtyMTJYNUNuUzFScFFFWFAxNHdYRCIsInR5cGUiOiJtZXNzYWdlIiwicm9sZSI6ImFzc2lzdGFudCIsIm1vZGVsIjoiY2xhdWRlLTMtNS1oYWlrdS0yMDI0MTAyMiIsImNvbnRlbnQiOlt7InR5cGUiOiJ0ZXh0IiwidGV4dCI6IkJhc2VkIG9uIHRoZSB3ZWF0aGVyIGluZm9ybWF0aW9uLCBoZXJlJ3MgdGhlIGN1cnJlbnQgd2VhdGhlciBpbiBCZXJsaW46XG4tIFRlbXBlcmF0dXJlOiAxNcKwQyAoNTnCsEYpXG4tIFdpbmQgU3BlZWQ6IDEwIGttL2hcblxuSXQgc2VlbXMgbGlrZSBhIG1pbGQgZGF5IGluIEJlcmxpbiB3aXRoIGEgbW9kZXJhdGUgYnJlZXplLiBUaGUgdGVtcGVyYXR1cmUgaXMgY29tZm9ydGFibGUsIHBlcmZlY3QgZm9yIGxpZ2h0IG91dGRvb3IgYWN0aXZpdGllcyBvciB3YWxraW5nIGFyb3VuZCB0aGUgY2l0eS4ifV0sInN0b3BfcmVhc29uIjoiZW5kX3R1cm4iLCJzdG9wX3NlcXVlbmNlIjpudWxsLCJ1c2FnZSI6eyJpbnB1dF90b2tlbnMiOjUxOSwib3V0cHV0X3Rva2VucyI6NzN9fQ== + recorded_at: Tue, 25 Mar 2025 21:43:20 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_function_calling_claude-3-5-haiku_can_use_tools_with_multi-turn_streaming_conversations_with_bedrock.yml b/spec/fixtures/vcr_cassettes/chat_function_calling_claude-3-5-haiku_can_use_tools_with_multi-turn_streaming_conversations_with_bedrock.yml new file mode 100644 index 000000000..3c950606a --- /dev/null +++ b/spec/fixtures/vcr_cassettes/chat_function_calling_claude-3-5-haiku_can_use_tools_with_multi-turn_streaming_conversations_with_bedrock.yml @@ -0,0 +1,365 @@ +--- +http_interactions: +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke-with-response-stream + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)"}],"temperature":0.7,"max_tokens":4096,"tools":[{"name":"weather","description":"Gets + current weather for a location","input_schema":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250325T220703Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - 175fe07b52825d214f2938f4dcfb11a1099924121ee86d46d6b027b10fa92fa4 + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250325/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=024e659098284d92279f67cd0b591e037a612f06c43f36626ce06748c1b1c8b7 + Content-Type: + - application/json + Accept: + - application/vnd.amazon.eventstream + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 25 Mar 2025 22:06:22 GMT + Content-Type: + - application/vnd.amazon.eventstream + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Amzn-Requestid: + - c620a31c-c1e9-461c-bda8-0fa5e2cdf972 + X-Amzn-Bedrock-Content-Type: + - application/json + body: + encoding: ASCII-8BIT + string: !binary |- + AAAB7gAAAEvYlO1qCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaWJXVnpjMkZuWlY5emRHRnlkQ0lzSW0xbGMzTmhaMlVpT25zaWFXUWlPaUp0YzJkZlltUnlhMTh3TVRkRFlYTm5SMWRDV1hVeFpFaFdWbmQwTkdGSFZVY2lMQ0owZVhCbElqb2liV1Z6YzJGblpTSXNJbkp2YkdVaU9pSmhjM05wYzNSaGJuUWlMQ0p0YjJSbGJDSTZJbU5zWVhWa1pTMHpMVFV0YUdGcGEzVXRNakF5TkRFd01qSWlMQ0pqYjI1MFpXNTBJanBiWFN3aWMzUnZjRjl5WldGemIyNGlPbTUxYkd3c0luTjBiM0JmYzJWeGRXVnVZMlVpT201MWJHd3NJblZ6WVdkbElqcDdJbWx1Y0hWMFgzUnZhMlZ1Y3lJNk16ZzVMQ0p2ZFhSd2RYUmZkRzlyWlc1eklqb3hmWDE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVoifXAr6J8AAAD8AAAASwno+i0LOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOXpkR0Z5ZENJc0ltbHVaR1Y0SWpvd0xDSmpiMjUwWlc1MFgySnNiMk5ySWpwN0luUjVjR1VpT2lKMFpYaDBJaXdpZEdWNGRDSTZJaUo5ZlE9PSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0QifZaMhKQAAADlAAAAS2QYD94LOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSk1aWFFpZlgwPSIsInAiOiJhYmNkZWZnIn095k2yAAABOwAAAEuZgR1DCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUlnYldVZ1kyaGxZMnNnZEdobElHTjFjbkpsYm5RZ2QyVmhkR2hsY2lCbWIzSWdRbVZ5YkdsdUlIVnphVzVuSW4xOSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLIn2WASsfAAABKgAAAEvEAaNxCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUlnZEdobElIQnliM1pwWkdWa0lHTnZiM0prYVc1aGRHVnpMaUo5ZlE9PSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUiJ944YSZQAAALcAAABLJsuTdQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5emRHOXdJaXdpYVc1a1pYZ2lPakI5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dSJ9wGABeAAAAWAAAABL1kLjmQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5emRHRnlkQ0lzSW1sdVpHVjRJam94TENKamIyNTBaVzUwWDJKc2IyTnJJanA3SW5SNWNHVWlPaUowYjI5c1gzVnpaU0lzSW1sa0lqb2lkRzl2YkhWZlltUnlhMTh3TVRWT1RWVmxhbVJYTmxCbVJEUlhXR3B2VWtWUlVsVWlMQ0p1WVcxbElqb2lkMlZoZEdobGNpSXNJbWx1Y0hWMElqcDdmWDE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1Qifa5smiEAAAD0AAAASzmYsewLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpveExDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWFXNXdkWFJmYW5OdmJsOWtaV3gwWVNJc0luQmhjblJwWVd4ZmFuTnZiaUk2SWlKOWZRPT0iLCJwIjoiYWJjZGVmIn3p9R6DAAABLQAAAEt2IX9hCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3hMQ0prWld4MFlTSTZleUowZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNkludGNJbXdpZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMDEyMzQ1NiJ9ARzv0QAAAS4AAABLMYEFsQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam94TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pYVc1d2RYUmZhbk52Ymw5a1pXeDBZU0lzSW5CaGNuUnBZV3hmYW5OdmJpSTZJbUYwYVhSMVpHVWlmWDA9IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzIn1oiWBuAAABJwAAAEs8kWfACzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3hMQ0prWld4MFlTSTZleUowZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNklsd2lPaUFpZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMCJ9izjqsAAAATMAAABLqfFWggs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam94TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pYVc1d2RYUmZhbk52Ymw5a1pXeDBZU0lzSW5CaGNuUnBZV3hmYW5OdmJpSTZJbHdpTlRJdU5USXdNRndpSW4xOSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMDEyMzQifQt8Q1sAAAEiAAAAS/Rx6LALOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpveExDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWFXNXdkWFJmYW5OdmJsOWtaV3gwWVNJc0luQmhjblJwWVd4ZmFuTnZiaUk2SWl3Z1hDSnNiMjVuYVhSMVpDSjlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSiJ9FP2w9AAAAP0AAABLNIjTnQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam94TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pYVc1d2RYUmZhbk52Ymw5a1pXeDBZU0lzSW5CaGNuUnBZV3hmYW5OdmJpSTZJbVZjSWpvZ1hDSmNJbjBpZlgwPSIsInAiOiJhYmMifbJaATUAAACsAAAASzH7NeYLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOXpkRzl3SWl3aWFXNWtaWGdpT2pGOSIsInAiOiJhYmNkZWZnaGlqIn31LGSlAAABEgAAAEtVUFA2CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaWJXVnpjMkZuWlY5a1pXeDBZU0lzSW1SbGJIUmhJanA3SW5OMGIzQmZjbVZoYzI5dUlqb2lkRzl2YkY5MWMyVWlMQ0p6ZEc5d1gzTmxjWFZsYm1ObElqcHVkV3hzZlN3aWRYTmhaMlVpT25zaWIzVjBjSFYwWDNSdmEyVnVjeUk2T0RoOWZRPT0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcCJ9Hf/T/wAAAVwAAABLspO2Hgs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2liV1Z6YzJGblpWOXpkRzl3SWl3aVlXMWhlbTl1TFdKbFpISnZZMnN0YVc1MmIyTmhkR2x2YmsxbGRISnBZM01pT25zaWFXNXdkWFJVYjJ0bGJrTnZkVzUwSWpvek9Ea3NJbTkxZEhCMWRGUnZhMlZ1UTI5MWJuUWlPalk0TENKcGJuWnZZMkYwYVc5dVRHRjBaVzVqZVNJNk16azBNeXdpWm1seWMzUkNlWFJsVEdGMFpXNWplU0k2T0RNeWZYMD0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSCJ9B57sAQ== + recorded_at: Tue, 25 Mar 2025 22:07:07 GMT +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke-with-response-stream + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)"},{"role":"assistant","content":[{"type":"text","text":"Let + me check the current weather for Berlin using the provided coordinates."},{"type":"tool_use","id":"toolu_bdrk_015NMUejdW6PfD4WXjoREQRU","name":"weather","input":{"latitude":"52.5200","longitude":""}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_015NMUejdW6PfD4WXjoREQRU","content":"Current + weather at 52.5200, : 15°C, Wind: 10 km/h"}]}],"temperature":0.7,"max_tokens":4096,"tools":[{"name":"weather","description":"Gets + current weather for a location","input_schema":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250325T222158Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - 39f2dab80df11c1de2f428b35b23d31293e8389166e7c31746c11a36b465a454 + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250325/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=3a59f20fac243e8a0965af2d1c08394196061d19d61d9b8c8049cb21b457de2f + Content-Type: + - application/json + Accept: + - application/vnd.amazon.eventstream + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 25 Mar 2025 22:21:16 GMT + Content-Type: + - application/vnd.amazon.eventstream + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Amzn-Requestid: + - c66f54ea-f947-4352-a007-6088a5cd3978 + X-Amzn-Bedrock-Content-Type: + - application/json + body: + encoding: ASCII-8BIT + string: !binary |- + AAABvAAAAEuaR3HBCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaWJXVnpjMkZuWlY5emRHRnlkQ0lzSW0xbGMzTmhaMlVpT25zaWFXUWlPaUp0YzJkZlltUnlhMTh3TVV4UVVHVjNibU15ZDNGTk5EUXpXR0ZZUVVaQllVRWlMQ0owZVhCbElqb2liV1Z6YzJGblpTSXNJbkp2YkdVaU9pSmhjM05wYzNSaGJuUWlMQ0p0YjJSbGJDSTZJbU5zWVhWa1pTMHpMVFV0YUdGcGEzVXRNakF5TkRFd01qSWlMQ0pqYjI1MFpXNTBJanBiWFN3aWMzUnZjRjl5WldGemIyNGlPbTUxYkd3c0luTjBiM0JmYzJWeGRXVnVZMlVpT201MWJHd3NJblZ6WVdkbElqcDdJbWx1Y0hWMFgzUnZhMlZ1Y3lJNk5UQTJMQ0p2ZFhSd2RYUmZkRzlyWlc1eklqb3lmWDE5IiwicCI6ImFiIn3X7BsWAAAA8gAAAEu22ERMCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTl6ZEdGeWRDSXNJbWx1WkdWNElqb3dMQ0pqYjI1MFpXNTBYMkpzYjJOcklqcDdJblI1Y0dVaU9pSjBaWGgwSWl3aWRHVjRkQ0k2SWlKOWZRPT0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3QifZMekHEAAAECAAAASzWwx7QLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSmNibHh1U1NKOWZRPT0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUYifdSSl4AAAAE2AAAAS2ER2fILOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSWdZWEJ2Ykc5bmFYcGxMQ0JpZFhRZ2FYUWdjMlZsYlhNZ2RHaGxjbVVpZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaIn0eru+5AAABOQAAAEvjQU4jCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUlnYldsbmFIUWdhR0YyWlNCaVpXVnVJR0VnYzIxaGJHd2dhWE56ZFdVZ2QybDBhQ0IwYUdVZ1puVnVZM1JwYjI0aWZYMD0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERSJ9tI0e6wAAAR4AAABLkKC9Nws6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJZ1kyRnNiQzRnVEdWMElHMWxJSFJ5ZVNCaFoyRnBiaUIzYVhSb0lHSnZkR2dpZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3gifRfBWvMAAAEeAAAAS5CgvTcLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSWdkR2hsSUd4aGRHbDBkV1JsSUdGdVpDQnNiMjVuYVhSMVpHVTZJbjE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGIn3DuoHjAAAA3wAAAEuPia/5CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTl6ZEc5d0lpd2lhVzVrWlhnaU9qQjkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NTY3OCJ933gtaAAAAWkAAABL21KB6As6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5emRHRnlkQ0lzSW1sdVpHVjRJam94TENKamIyNTBaVzUwWDJKc2IyTnJJanA3SW5SNWNHVWlPaUowYjI5c1gzVnpaU0lzSW1sa0lqb2lkRzl2YkhWZlltUnlhMTh3TVRKbVRETmxabGhDY2tWaVozRjFRMDVsYzFkNlJtUWlMQ0p1WVcxbElqb2lkMlZoZEdobGNpSXNJbWx1Y0hWMElqcDdmWDE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIifTSquX4AAAEkAAAAS3sxHRALOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpveExDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWFXNXdkWFJmYW5OdmJsOWtaV3gwWVNJc0luQmhjblJwWVd4ZmFuTnZiaUk2SWlKOWZRPT0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxIn065KDUAAABDwAAAEvNIAMFCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3hMQ0prWld4MFlTSTZleUowZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNkludGNJbXhoZEdsMGRXUmxJbjE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dSJ9IgFU+gAAASYAAABLAfFOcAs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam94TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pYVc1d2RYUmZhbk52Ymw5a1pXeDBZU0lzSW5CaGNuUnBZV3hmYW5OdmJpSTZJbHdpT2lCY0lqVXlMalV5TURBaWZYMD0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTiJ9BRcswQAAAPsAAABLu8gmPQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam94TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pYVc1d2RYUmZhbk52Ymw5a1pXeDBZU0lzSW5CaGNuUnBZV3hmYW5OdmJpSTZJbHdpSW4xOSIsInAiOiJhYmNkZWZnaGlqa2xtIn3Af37iAAABKgAAAEvEAaNxCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3hMQ0prWld4MFlTSTZleUowZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNklpd2dYQ0pzYjI1bmFYUWlmWDA9IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVViJ9jr0x3QAAAQsAAABLOKClxQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam94TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pYVc1d2RYUmZhbk52Ymw5a1pXeDBZU0lzSW5CaGNuUnBZV3hmYW5OdmJpSTZJblZrWlZ3aU9pSjlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dSJ9v/X/nAAAASYAAABLAfFOcAs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam94TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pYVc1d2RYUmZhbk52Ymw5a1pXeDBZU0lzSW5CaGNuUnBZV3hmYW5OdmJpSTZJaUJjSWx3aWZTSjlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVViJ9nI5PDAAAAM4AAABL0gkRyws6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5emRHOXdJaXdpYVc1a1pYZ2lPakY5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSIn3w8dW3AAABBQAAAEuHkBukCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaWJXVnpjMkZuWlY5a1pXeDBZU0lzSW1SbGJIUmhJanA3SW5OMGIzQmZjbVZoYzI5dUlqb2lkRzl2YkY5MWMyVWlMQ0p6ZEc5d1gzTmxjWFZsYm1ObElqcHVkV3hzZlN3aWRYTmhaMlVpT25zaWIzVjBjSFYwWDNSdmEyVnVjeUk2TVRBMmZYMD0iLCJwIjoiYWJjIn3rYdycAAABdwAAAEsEgqgLCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaWJXVnpjMkZuWlY5emRHOXdJaXdpWVcxaGVtOXVMV0psWkhKdlkyc3RhVzUyYjJOaGRHbHZiazFsZEhKcFkzTWlPbnNpYVc1d2RYUlViMnRsYmtOdmRXNTBJam8xTURZc0ltOTFkSEIxZEZSdmEyVnVRMjkxYm5RaU9qZ3lMQ0pwYm5adlkyRjBhVzl1VEdGMFpXNWplU0k2TWpjeE5Dd2labWx5YzNSQ2VYUmxUR0YwWlc1amVTSTZOalF4ZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMDEyMzQ1Njc4In37k5td + recorded_at: Tue, 25 Mar 2025 22:22:00 GMT +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke-with-response-stream + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)"},{"role":"assistant","content":[{"type":"text","text":"Let + me check the current weather for Berlin using the provided coordinates."},{"type":"tool_use","id":"toolu_bdrk_015NMUejdW6PfD4WXjoREQRU","name":"weather","input":{"latitude":"52.5200","longitude":""}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_015NMUejdW6PfD4WXjoREQRU","content":"Current + weather at 52.5200, : 15°C, Wind: 10 km/h"}]},{"role":"assistant","content":[{"type":"text","text":"\n\nI + apologize, but it seems there might have been a small issue with the function + call. Let me try again with both the latitude and longitude:"},{"type":"tool_use","id":"toolu_bdrk_012fL3efXBrEbgquCNesWzFd","name":"weather","input":{"latitude":"52.5200","longitude":""}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_012fL3efXBrEbgquCNesWzFd","content":"Current + weather at 52.5200, : 15°C, Wind: 10 km/h"}]}],"temperature":0.7,"max_tokens":4096,"tools":[{"name":"weather","description":"Gets + current weather for a location","input_schema":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250325T222200Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - 6f22a6d3fc17ab5c783c0edfcd330aaa63e8ef18ead4d0982665011e447e5224 + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250325/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=cdeb0b08112c622175fa8480bd344781e6ef1f5be2e8c7ba02feb5adbcf177dd + Content-Type: + - application/json + Accept: + - application/vnd.amazon.eventstream + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 25 Mar 2025 22:21:19 GMT + Content-Type: + - application/vnd.amazon.eventstream + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Amzn-Requestid: + - e5182753-ee8f-4ad4-af75-406472fe4294 + X-Amzn-Bedrock-Content-Type: + - application/json + body: + encoding: ASCII-8BIT + string: !binary |- + AAAB3wAAAEtE1XxcCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaWJXVnpjMkZuWlY5emRHRnlkQ0lzSW0xbGMzTmhaMlVpT25zaWFXUWlPaUp0YzJkZlltUnlhMTh3TVRWWFJGUjNjRE14WVZVNVVXaDROa3haT1VkRWMzWWlMQ0owZVhCbElqb2liV1Z6YzJGblpTSXNJbkp2YkdVaU9pSmhjM05wYzNSaGJuUWlMQ0p0YjJSbGJDSTZJbU5zWVhWa1pTMHpMVFV0YUdGcGEzVXRNakF5TkRFd01qSWlMQ0pqYjI1MFpXNTBJanBiWFN3aWMzUnZjRjl5WldGemIyNGlPbTUxYkd3c0luTjBiM0JmYzJWeGRXVnVZMlVpT201MWJHd3NJblZ6WVdkbElqcDdJbWx1Y0hWMFgzUnZhMlZ1Y3lJNk5qUXhMQ0p2ZFhSd2RYUmZkRzlyWlc1eklqb3lmWDE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSksifVTHfJYAAAERAAAASxLwKuYLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOXpkR0Z5ZENJc0ltbHVaR1Y0SWpvd0xDSmpiMjUwWlc1MFgySnNiMk5ySWpwN0luUjVjR1VpT2lKMFpYaDBJaXdpZEdWNGRDSTZJaUo5ZlE9PSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFkifaHOKG0AAADsAAAAS2kIba8LOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSmNibHh1U1NKOWZRPT0iLCJwIjoiYWJjZGVmZ2hpaiJ9u30z/wAAAScAAABLPJFnwAs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJZ1lYQnZiRzluYVhwbElHWnZjaUIwYUdVZ2FXNWpiMjUyWlc1cFpXNWpaUzRnU1hRaWZYMD0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkMifQ/gt2IAAAFPAAAAS5XTW0wLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSWdZWEJ3WldGeWN5QjBhR0YwSUhSb1pTQjNaV0YwYUdWeUlHWjFibU4wYVc5dUlHbHpJRzV2ZENCM2IzSnJhVzVuSUdOdmNuSmxZM1JzZVNCaGRDSjlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGRyJ9M2w3hgAAASoAAABLxAGjcQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJZ2RHaGxJRzF2YldWdWRDNGdTRzkzWlhabGNpd2dZbUZ6WldRZ2IyNGdkR2hsSUhCaGNuUnBZV3dpZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3gifVfgpZsAAAEqAAAAS8QBo3ELOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSWdhVzVtYjNKdFlYUnBiMjRnY21WalpXbDJaV1FzSUhSb1pTQjBaVzF3WlhKaGRIVnlaU0JwYmlCQ1pYSnNhVzRnYVhNZ1lYSnZkVzRpZlgwPSIsInAiOiJhYmNkIn3cT7qKAAABCwAAAEs4oKXFCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUprSURFMXdyQkRJSGRwZEdnZ1lTQjNhVzRpZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5In1tMgUMAAABJgAAAEsB8U5wCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUprSUhOd1pXVmtJRzltSURFd0lHdHRMMmd1SUNKOWZRPT0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWIn0l8U6EAAABIQAAAEuz0ZJgCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUpjYmx4dVJtOXlJSFJvWlNCdGIzTjBJR0ZqWTNWeVlYUmxJR0Z1WkNCMWNDMTBieTBpZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2dyJ9YBy0zAAAASYAAABLAfFOcAs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lKa1lYUmxJSGRsWVhSb1pYSWdhVzVtYjNKdFlYUnBiMjRzSUVrZ2NtVmpiMjF0Wlc0aWZYMD0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQiJ9dtqPDwAAASAAAABLjrG70As6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lKa0lHTm9aV05yYVc1bklHRWdiRzlqWVd3Z2QyVmhkR2hsY2lCelpYSjJhV05sSUc5eUlIZGxZbk5wZEdVdUlGZHZkV3dpZlgwPSIsInAiOiJhYiJ9jhGL/AAAAUQAAABL4gNqXQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lKa0lIbHZkU0JzYVd0bElHMWxJSFJ2SUdobGJIQWdlVzkxSUdacGJtUWdZU0J5Wld4cFlXSnNaU0IzWldGMGFHVnlJbjE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUCJ9bX2JYQAAASwAAABLS0FW0Qs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJZ2MyOTFjbU5sSUdadmNpQkNaWEpzYVc0L0luMTkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NSJ9DzGoPAAAAKcAAABLRisE9ws6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5emRHOXdJaXdpYVc1a1pYZ2lPakI5IiwicCI6ImFiY2RlIn14AZkDAAABPQAAAEsWwejjCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaWJXVnpjMkZuWlY5a1pXeDBZU0lzSW1SbGJIUmhJanA3SW5OMGIzQmZjbVZoYzI5dUlqb2laVzVrWDNSMWNtNGlMQ0p6ZEc5d1gzTmxjWFZsYm1ObElqcHVkV3hzZlN3aWRYTmhaMlVpT25zaWIzVjBjSFYwWDNSdmEyVnVjeUk2T1RoOWZRPT0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NTYifRNaFOAAAAF1AAAAS35C+2sLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pYldWemMyRm5aVjl6ZEc5d0lpd2lZVzFoZW05dUxXSmxaSEp2WTJzdGFXNTJiMk5oZEdsdmJrMWxkSEpwWTNNaU9uc2lhVzV3ZFhSVWIydGxia052ZFc1MElqbzJOREVzSW05MWRIQjFkRlJ2YTJWdVEyOTFiblFpT2prNExDSnBiblp2WTJGMGFXOXVUR0YwWlc1amVTSTZNekE1TVN3aVptbHljM1JDZVhSbFRHRjBaVzVqZVNJNk5USXdmWDA9IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU2In0G4VOT + recorded_at: Tue, 25 Mar 2025 22:22:04 GMT +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke-with-response-stream + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)"},{"role":"assistant","content":[{"type":"text","text":"Let + me check the current weather for Berlin using the provided coordinates."},{"type":"tool_use","id":"toolu_bdrk_015NMUejdW6PfD4WXjoREQRU","name":"weather","input":{"latitude":"52.5200","longitude":""}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_015NMUejdW6PfD4WXjoREQRU","content":"Current + weather at 52.5200, : 15°C, Wind: 10 km/h"}]},{"role":"assistant","content":[{"type":"text","text":"\n\nI + apologize, but it seems there might have been a small issue with the function + call. Let me try again with both the latitude and longitude:"},{"type":"tool_use","id":"toolu_bdrk_012fL3efXBrEbgquCNesWzFd","name":"weather","input":{"latitude":"52.5200","longitude":""}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_012fL3efXBrEbgquCNesWzFd","content":"Current + weather at 52.5200, : 15°C, Wind: 10 km/h"}]},{"role":"assistant","content":"\n\nI + apologize for the inconvenience. It appears that the weather function is not + working correctly at the moment. However, based on the partial information + received, the temperature in Berlin is around 15°C with a wind speed of 10 + km/h. \n\nFor the most accurate and up-to-date weather information, I recommend + checking a local weather service or website. Would you like me to help you + find a reliable weather source for Berlin?"},{"role":"user","content":"What''s + the weather in Paris? (48.8575, 2.3514)"}],"temperature":0.7,"max_tokens":4096,"tools":[{"name":"weather","description":"Gets + current weather for a location","input_schema":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250325T222204Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - 576502aa6ad10130bfcb9b581d4ef6dca8e199c1e11e4f10150a2a89e24d06ad + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250325/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=54ec86ef80dda18c124d1176efd1bf52d32cf4086264da7af276b5dd3d460533 + Content-Type: + - application/json + Accept: + - application/vnd.amazon.eventstream + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 25 Mar 2025 22:21:22 GMT + Content-Type: + - application/vnd.amazon.eventstream + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Amzn-Requestid: + - 31051375-0aed-43ae-901e-e9becd7567c6 + X-Amzn-Bedrock-Content-Type: + - application/json + body: + encoding: ASCII-8BIT + string: !binary |- + AAAByQAAAEurdR5+CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaWJXVnpjMkZuWlY5emRHRnlkQ0lzSW0xbGMzTmhaMlVpT25zaWFXUWlPaUp0YzJkZlltUnlhMTh3TVRKSVJIVnlZWEJZYm5RMldrdDFZVFYxT1ROaFpIRWlMQ0owZVhCbElqb2liV1Z6YzJGblpTSXNJbkp2YkdVaU9pSmhjM05wYzNSaGJuUWlMQ0p0YjJSbGJDSTZJbU5zWVhWa1pTMHpMVFV0YUdGcGEzVXRNakF5TkRFd01qSWlMQ0pqYjI1MFpXNTBJanBiWFN3aWMzUnZjRjl5WldGemIyNGlPbTUxYkd3c0luTjBiM0JmYzJWeGRXVnVZMlVpT201MWJHd3NJblZ6WVdkbElqcDdJbWx1Y0hWMFgzUnZhMlZ1Y3lJNk56WXhMQ0p2ZFhSd2RYUmZkRzlyWlc1eklqb3lmWDE5IiwicCI6ImFiY2RlZmdoaWprbG1ubyJ9w/PgCQAAAOAAAABLrPiArgs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5emRHRnlkQ0lzSW1sdVpHVjRJam93TENKamIyNTBaVzUwWDJKc2IyTnJJanA3SW5SNWNHVWlPaUowWlhoMElpd2lkR1Y0ZENJNklpSjlmUT09IiwicCI6ImFiIn2SGprmAAABGwAAAEtYQDJHCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUpKSjJ4c0luMTkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NTY3OCJ9w+GVFAAAAWEAAABL6yLKKQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJZ1kyaGxZMnNnZEdobElHTjFjbkpsYm5RZ2QyVmhkR2hsY2lCbWIzSWdVR0Z5YVhNZ2RYTnBibWNnZEdobElIQnliM1pwWkdWa0lHTnZiM0prYVc1aGRHVnpMaUo5ZlE9PSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRIn2D3tCTAAAAyAAAAEtdSeRrCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTl6ZEc5d0lpd2lhVzVrWlhnaU9qQjkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0wifYcXTLMAAAE4AAAAS94hZ5MLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOXpkR0Z5ZENJc0ltbHVaR1Y0SWpveExDSmpiMjUwWlc1MFgySnNiMk5ySWpwN0luUjVjR1VpT2lKMGIyOXNYM1Z6WlNJc0ltbGtJam9pZEc5dmJIVmZZbVJ5YTE4d01WSnRWM0ZaWnpOb00xcGpiVzlwWkROV2NYWjRXRElpTENKdVlXMWxJam9pZDJWaGRHaGxjaUlzSW1sdWNIVjBJanA3ZlgxOSIsInAiOiJhYmNkZWYifT9xji8AAAEIAAAAS38A3xULOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpveExDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWFXNXdkWFJmYW5OdmJsOWtaV3gwWVNJc0luQmhjblJwWVd4ZmFuTnZiaUk2SWlKOWZRPT0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoifdcQu9oAAAD9AAAASzSI050LOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpveExDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWFXNXdkWFJmYW5OdmJsOWtaV3gwWVNJc0luQmhjblJwWVd4ZmFuTnZiaUk2SW50Y0lteGhkQ0o5ZlE9PSIsInAiOiJhYmNkZWZnIn0pr17dAAABKQAAAEuDodmhCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3hMQ0prWld4MFlTSTZleUowZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNkltbDBkV1JsWENJaWZYMD0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZIn04WAFFAAABKQAAAEuDodmhCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3hMQ0prWld4MFlTSTZleUowZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNklqb2dYQ0kwT0M0aWZYMD0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZIn2eMvOnAAAA+QAAAEvBCHVdCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3hMQ0prWld4MFlTSTZleUowZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNklqZzFOelVpZlgwPSIsInAiOiJhYmNkZWZnIn02xOytAAABIAAAAEuOsbvQCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3hMQ0prWld4MFlTSTZleUowZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNklsd2lJbjE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYIn1o8KJHAAABFAAAAEvaEKWWCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3hMQ0prWld4MFlTSTZleUowZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNklpd2dYQ0pzYnlKOWZRPT0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNEIn1b6NSkAAABCwAAAEs4oKXFCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3hMQ0prWld4MFlTSTZleUowZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNkltNW5JbjE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDIn2CDdXjAAABHQAAAEvXAMfnCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3hMQ0prWld4MFlTSTZleUowZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNkltbDBkV1JsWENJNklGd2lYQ0o5SW4xOSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFIn08owdtAAAArwAAAEt2W082CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTl6ZEc5d0lpd2lhVzVrWlhnaU9qRjkiLCJwIjoiYWJjZGVmZ2hpamtsbSJ93cUYDwAAARkAAABLIoBhJws6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2liV1Z6YzJGblpWOWtaV3gwWVNJc0ltUmxiSFJoSWpwN0luTjBiM0JmY21WaGMyOXVJam9pZEc5dmJGOTFjMlVpTENKemRHOXdYM05sY1hWbGJtTmxJanB1ZFd4c2ZTd2lkWE5oWjJVaU9uc2liM1YwY0hWMFgzUnZhMlZ1Y3lJNk9EaDlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3In3z0VQIAAABYgAAAEusgrD5CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaWJXVnpjMkZuWlY5emRHOXdJaXdpWVcxaGVtOXVMV0psWkhKdlkyc3RhVzUyYjJOaGRHbHZiazFsZEhKcFkzTWlPbnNpYVc1d2RYUlViMnRsYmtOdmRXNTBJam8zTmpFc0ltOTFkSEIxZEZSdmEyVnVRMjkxYm5RaU9qWTBMQ0pwYm5adlkyRjBhVzl1VEdGMFpXNWplU0k2TWpNME1Td2labWx5YzNSQ2VYUmxUR0YwWlc1amVTSTZOalk0ZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OIn2FY7Bn + recorded_at: Tue, 25 Mar 2025 22:22:06 GMT +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke-with-response-stream + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)"},{"role":"assistant","content":[{"type":"text","text":"Let + me check the current weather for Berlin using the provided coordinates."},{"type":"tool_use","id":"toolu_bdrk_015NMUejdW6PfD4WXjoREQRU","name":"weather","input":{"latitude":"52.5200","longitude":""}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_015NMUejdW6PfD4WXjoREQRU","content":"Current + weather at 52.5200, : 15°C, Wind: 10 km/h"}]},{"role":"assistant","content":[{"type":"text","text":"\n\nI + apologize, but it seems there might have been a small issue with the function + call. Let me try again with both the latitude and longitude:"},{"type":"tool_use","id":"toolu_bdrk_012fL3efXBrEbgquCNesWzFd","name":"weather","input":{"latitude":"52.5200","longitude":""}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_012fL3efXBrEbgquCNesWzFd","content":"Current + weather at 52.5200, : 15°C, Wind: 10 km/h"}]},{"role":"assistant","content":"\n\nI + apologize for the inconvenience. It appears that the weather function is not + working correctly at the moment. However, based on the partial information + received, the temperature in Berlin is around 15°C with a wind speed of 10 + km/h. \n\nFor the most accurate and up-to-date weather information, I recommend + checking a local weather service or website. Would you like me to help you + find a reliable weather source for Berlin?"},{"role":"user","content":"What''s + the weather in Paris? (48.8575, 2.3514)"},{"role":"assistant","content":[{"type":"text","text":"I''ll + check the current weather for Paris using the provided coordinates."},{"type":"tool_use","id":"toolu_bdrk_01RmWqYg3h3Zcmoid3VqvxX2","name":"weather","input":{"latitude":"48.8575","longitude":""}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_01RmWqYg3h3Zcmoid3VqvxX2","content":"Current + weather at 48.8575, : 15°C, Wind: 10 km/h"}]}],"temperature":0.7,"max_tokens":4096,"tools":[{"name":"weather","description":"Gets + current weather for a location","input_schema":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250325T222206Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - 55a01ca368111dc26dae6f75321c82b5c411e7d8083db5351d2999b156e68018 + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250325/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=84ee5e6fcd96f9733319574f4bc5c7034e14f337558ece7b86c4055ef8ea3e9e + Content-Type: + - application/json + Accept: + - application/vnd.amazon.eventstream + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 25 Mar 2025 22:21:25 GMT + Content-Type: + - application/vnd.amazon.eventstream + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Amzn-Requestid: + - 8091ccc9-47ea-4ec6-8019-713df7fd6965 + X-Amzn-Bedrock-Content-Type: + - application/json + body: + encoding: ASCII-8BIT + string: !binary |- + AAAB7wAAAEvl9MTaCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaWJXVnpjMkZuWlY5emRHRnlkQ0lzSW0xbGMzTmhaMlVpT25zaWFXUWlPaUp0YzJkZlltUnlhMTh3TVRKbVFtWnJWMlpuV0RGaVNFcGtZV3RuWVVwWVUzUWlMQ0owZVhCbElqb2liV1Z6YzJGblpTSXNJbkp2YkdVaU9pSmhjM05wYzNSaGJuUWlMQ0p0YjJSbGJDSTZJbU5zWVhWa1pTMHpMVFV0YUdGcGEzVXRNakF5TkRFd01qSWlMQ0pqYjI1MFpXNTBJanBiWFN3aWMzUnZjRjl5WldGemIyNGlPbTUxYkd3c0luTjBiM0JmYzJWeGRXVnVZMlVpT201MWJHd3NJblZ6WVdkbElqcDdJbWx1Y0hWMFgzUnZhMlZ1Y3lJNk9EYzRMQ0p2ZFhSd2RYUmZkRzlyWlc1eklqb3pmWDE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowIn1UnSwpAAAA9QAAAEsE+JhcCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTl6ZEdGeWRDSXNJbWx1WkdWNElqb3dMQ0pqYjI1MFpXNTBYMkpzYjJOcklqcDdJblI1Y0dVaU9pSjBaWGgwSWl3aWRHVjRkQ0k2SWlKOWZRPT0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnciffZcoq0AAAEHAAAAS/1QSMQLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSmNibHh1U1NCaGNHOXNiMmNpZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQyJ9zVTJAgAAAQoAAABLBcCMdQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lKcGVtVXNJR0oxZENCMGFHVnlaU0J6WldWdGN5SjlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0In0lDx5XAAABPAAAAEsrocFTCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUlnZEc4Z1ltVWdZVzRnYjI1bmIybHVaeUJwYzNOMVpTQjNhWFJvSUhSb1pTQjNaV0YwYUdWeUluMTkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVCJ9fNg9IQAAAQ8AAABLzSADBQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJZ1puVnVZM1JwYjI0dUlFeGxkQ0J0WlNCMGNua2dZV2RoYVc0Z2QybDBhQ0o5ZlE9PSIsInAiOiJhYmNkZWZnaGkifeqlzTMAAAEAAAAAS09wlNQLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSWdkR2hsSUdaMWJHd2dZMjl2Y21ScGJtRjBaWE02SW4xOSIsInAiOiJhYmNkZWZnaGlqIn1Vnw6BAAAA1wAAAEu/+eQ4CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTl6ZEc5d0lpd2lhVzVrWlhnaU9qQjkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWjAifYRP1sIAAAFXAAAAS8VDhw8LOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOXpkR0Z5ZENJc0ltbHVaR1Y0SWpveExDSmpiMjUwWlc1MFgySnNiMk5ySWpwN0luUjVjR1VpT2lKMGIyOXNYM1Z6WlNJc0ltbGtJam9pZEc5dmJIVmZZbVJ5YTE4d01VRnpNVkJaVjJneVdFczFRMmxYWVhFNE5HazBWMjRpTENKdVlXMWxJam9pZDJWaGRHaGxjaUlzSW1sdWNIVjBJanA3ZlgxOSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLIn1dkjI/AAAA/gAAAEtzKKlNCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3hMQ0prWld4MFlTSTZleUowZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNklpSjlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3AifcjktS0AAAEVAAAAS+dwjCYLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpveExDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWFXNXdkWFJmYW5OdmJsOWtaV3gwWVNJc0luQmhjblJwWVd4ZmFuTnZiaUk2SW50Y0lteGhkR2wwZFdSbEluMTkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBIn0l2I/3AAAA+wAAAEu7yCY9CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3hMQ0prWld4MFlTSTZleUowZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNklsd2lPaUJjSWlKOWZRPT0iLCJwIjoiYWJjZGUifTqPPewAAAEQAAAASy+QA1YLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpveExDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWFXNXdkWFJmYW5OdmJsOWtaV3gwWVNJc0luQmhjblJwWVd4ZmFuTnZiaUk2SWpRNExqZ2lmWDA9IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDRCJ9Y/78mAAAAPsAAABLu8gmPQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam94TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pYVc1d2RYUmZhbk52Ymw5a1pXeDBZU0lzSW5CaGNuUnBZV3hmYW5OdmJpSTZJalUzSW4xOSIsInAiOiJhYmNkZWZnaGlqa2xtIn2HhxepAAAA/QAAAEs0iNOdCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3hMQ0prWld4MFlTSTZleUowZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNklqVmNJaUo5ZlE9PSIsInAiOiJhYmNkZWZnaGlqayJ95TO/JAAAATIAAABLlJF/Mgs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam94TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pYVc1d2RYUmZhbk52Ymw5a1pXeDBZU0lzSW5CaGNuUnBZV3hmYW5OdmJpSTZJaXdnWENKc2IyNGlmWDA9IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU2NyJ9bmNbEQAAASIAAABL9HHosAs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam94TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pYVc1d2RYUmZhbk52Ymw5a1pXeDBZU0lzSW5CaGNuUnBZV3hmYW5OdmJpSTZJbWRwZEhWa1pWd2lPaUJjSWpJaWZYMD0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKIn2HjGX4AAABBQAAAEuHkBukCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3hMQ0prWld4MFlTSTZleUowZVhCbElqb2lhVzV3ZFhSZmFuTnZibDlrWld4MFlTSXNJbkJoY25ScFlXeGZhbk52YmlJNklpNHpOVEUwWENKOUluMTkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vIn1dVgocAAAApgAAAEt7Sy1HCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTl6ZEc5d0lpd2lhVzVrWlhnaU9qRjkiLCJwIjoiYWJjZCJ9fFYeiwAAASoAAABLxAGjcQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2liV1Z6YzJGblpWOWtaV3gwWVNJc0ltUmxiSFJoSWpwN0luTjBiM0JmY21WaGMyOXVJam9pZEc5dmJGOTFjMlVpTENKemRHOXdYM05sY1hWbGJtTmxJanB1ZFd4c2ZTd2lkWE5oWjJVaU9uc2liM1YwY0hWMFgzUnZhMlZ1Y3lJNk1UQXlmWDA9IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU4ifVrDDRIAAAFTAAAASzDDIc8LOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pYldWemMyRm5aVjl6ZEc5d0lpd2lZVzFoZW05dUxXSmxaSEp2WTJzdGFXNTJiMk5oZEdsdmJrMWxkSEpwWTNNaU9uc2lhVzV3ZFhSVWIydGxia052ZFc1MElqbzROemdzSW05MWRIQjFkRlJ2YTJWdVEyOTFiblFpT2pjd0xDSnBiblp2WTJGMGFXOXVUR0YwWlc1amVTSTZNakF6TlN3aVptbHljM1JDZVhSbFRHRjBaVzVqZVNJNk1UYzFNbjE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHkifekoGwc= + recorded_at: Tue, 25 Mar 2025 22:22:08 GMT +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke-with-response-stream + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"What''s + the weather in Berlin? (52.5200, 13.4050)"},{"role":"assistant","content":[{"type":"text","text":"Let + me check the current weather for Berlin using the provided coordinates."},{"type":"tool_use","id":"toolu_bdrk_015NMUejdW6PfD4WXjoREQRU","name":"weather","input":{"latitude":"52.5200","longitude":""}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_015NMUejdW6PfD4WXjoREQRU","content":"Current + weather at 52.5200, : 15°C, Wind: 10 km/h"}]},{"role":"assistant","content":[{"type":"text","text":"\n\nI + apologize, but it seems there might have been a small issue with the function + call. Let me try again with both the latitude and longitude:"},{"type":"tool_use","id":"toolu_bdrk_012fL3efXBrEbgquCNesWzFd","name":"weather","input":{"latitude":"52.5200","longitude":""}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_012fL3efXBrEbgquCNesWzFd","content":"Current + weather at 52.5200, : 15°C, Wind: 10 km/h"}]},{"role":"assistant","content":"\n\nI + apologize for the inconvenience. It appears that the weather function is not + working correctly at the moment. However, based on the partial information + received, the temperature in Berlin is around 15°C with a wind speed of 10 + km/h. \n\nFor the most accurate and up-to-date weather information, I recommend + checking a local weather service or website. Would you like me to help you + find a reliable weather source for Berlin?"},{"role":"user","content":"What''s + the weather in Paris? (48.8575, 2.3514)"},{"role":"assistant","content":[{"type":"text","text":"I''ll + check the current weather for Paris using the provided coordinates."},{"type":"tool_use","id":"toolu_bdrk_01RmWqYg3h3Zcmoid3VqvxX2","name":"weather","input":{"latitude":"48.8575","longitude":""}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_01RmWqYg3h3Zcmoid3VqvxX2","content":"Current + weather at 48.8575, : 15°C, Wind: 10 km/h"}]},{"role":"assistant","content":[{"type":"text","text":"\n\nI + apologize, but there seems to be an ongoing issue with the weather function. + Let me try again with the full coordinates:"},{"type":"tool_use","id":"toolu_bdrk_01As1PYWh2XK5CiWaq84i4Wn","name":"weather","input":{"latitude":"48.8575","longitude":"2.3514"}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_01As1PYWh2XK5CiWaq84i4Wn","content":"Current + weather at 48.8575, 2.3514: 15°C, Wind: 10 km/h"}]}],"temperature":0.7,"max_tokens":4096,"tools":[{"name":"weather","description":"Gets + current weather for a location","input_schema":{"type":"object","properties":{"latitude":{"type":"string","description":"Latitude + (e.g., 52.5200)"},"longitude":{"type":"string","description":"Longitude (e.g., + 13.4050)"}},"required":["latitude","longitude"]}}]}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250325T222208Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - 7792064bc9716dd94455bb5c1a8d5d650a98b3fb7bc797ef6601a345c57a22e6 + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250325/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=2c9da80fc819e6b3df19a0ed5d746f794ef782a32be5cdfdc65a1463a819a30d + Content-Type: + - application/json + Accept: + - application/vnd.amazon.eventstream + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 25 Mar 2025 22:21:27 GMT + Content-Type: + - application/vnd.amazon.eventstream + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Amzn-Requestid: + - 742ce604-99db-4386-ab42-fd2969abe68d + X-Amzn-Bedrock-Content-Type: + - application/json + body: + encoding: ASCII-8BIT + string: !binary |- + AAAB2wAAAEuxVdqcCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaWJXVnpjMkZuWlY5emRHRnlkQ0lzSW0xbGMzTmhaMlVpT25zaWFXUWlPaUp0YzJkZlltUnlhMTh3TVZsUlFVdEtNbFJRVFcxcFZISXliVzFFTTBOdldGSWlMQ0owZVhCbElqb2liV1Z6YzJGblpTSXNJbkp2YkdVaU9pSmhjM05wYzNSaGJuUWlMQ0p0YjJSbGJDSTZJbU5zWVhWa1pTMHpMVFV0YUdGcGEzVXRNakF5TkRFd01qSWlMQ0pqYjI1MFpXNTBJanBiWFN3aWMzUnZjRjl5WldGemIyNGlPbTUxYkd3c0luTjBiM0JmYzJWeGRXVnVZMlVpT201MWJHd3NJblZ6WVdkbElqcDdJbWx1Y0hWMFgzUnZhMlZ1Y3lJNk1UQXhPU3dpYjNWMGNIVjBYM1J2YTJWdWN5STZNMzE5ZlE9PSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQyJ9RAzfuwAAARIAAABLVVBQNgs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5emRHRnlkQ0lzSW1sdVpHVjRJam93TENKamIyNTBaVzUwWDJKc2IyTnJJanA3SW5SNWNHVWlPaUowWlhoMElpd2lkR1Y0ZENJNklpSjlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVoifRCdkjgAAAElAAAAS0ZRNKALOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSmNibHh1U1NCaGNHOXNiMmNpZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMDEyMzQ1NiJ9DDsUngAAATAAAABL7lEsUgs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lKcGVtVWdabTl5SUhSb1pTQnBibU52Ym5OcGMzUmxiblFnY21WemRXeDBjeTRnVkdobElIZGxZWFJvWlhJZ1puVnVZM1JwYjI0aWZYMD0iLCJwIjoiYWJjZGVmZ2hpamtsbW4ifUIgGzsAAAFBAAAASyrj5S0LOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSWdZWEJ3WldGeWN5QjBieUJpWlNCbGVIQmxjbWxsYm1OcGJtY2djMjl0WlNCMFpXTm9ibWxqWVd3Z1pHbG1abWxqZFd4MGFXVnpMaUo5ZlE9PSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekEifcWOxSMAAAExAAAAS9MxBeILOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSWdWR2hsSUhCaGNuUnBZV3dnYVc1bWIzSnRZWFJwYjI0Z2MzVm5aMlZ6ZEhNZ2RHaGhkQ0JRWVhKcGN5QnBjeUJqZFhKeVpXNTBiSGtpZlgwPSIsInAiOiJhYmNkZWZnaGlqayJ9DDFZuwAAAUMAAABLUCO2TQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJZ1lYUWdNVFhDc0VNZ2QybDBhQ0JoSUhkcGJtUWdjM0JsWldRZ2IyWWdNVEFnSW4xOSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMDEyMzQ1Njc4In2sHCXeAAABQgAAAEttQ5/9CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUpyYlM5b0xpQmNibHh1U0c5M1pYWmxjaXdnWjJsMlpXNGdkR2hsSUhKbGNHVmhkR1VpZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMDEyMyJ9KrkG6QAAAWMAAABLkeKZSQs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lKa0lHbGtaVzUwYVdOaGJDQnlaV0ZrYVc1bmN5Qm1iM0lnWkdsbVptVnlaVzUwSUd4dlkyRjBhVzl1Y3l3Z1NTQmpZVzV1YjNRZ1kyOXVabWtpZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMDEyMzQifaKmNWAAAAF3AAAASwSCqAsLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSmtaVzUwYkhrZ1kyOXVabWx5YlNCMGFHVWdZV05qZFhKaFkza2diMllnZEdocGN5QnBibVp2Y20xaGRHbHZiaTRnUm05eUlIUm9aU0J0YjNOMElISmxiR2xoWW14bElHRnVJbjE5IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU2NzgifcrUOHUAAAFGAAAAS5jDOT0LOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSmtJR04xY25KbGJuUWdkMlZoZEdobGNpQnBibVp2Y20xaGRHbHZiaUJtYjNJZ1VHRnlhWE1zSUVrZ2NtVmpiMjF0Wlc0aWZYMD0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTiJ9PJAD0AAAARIAAABLVVBQNgs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lKa0lHTm9aV05yYVc1bklHRWdiRzlqWVd3Z2QyVmhkR2hsY2lCelpYSjJhV05sSUc5eUlHRWlmWDA9IiwicCI6ImFiY2QifVJC0IsAAAElAAAAS0ZRNKALOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSWdjbVZ3ZFhSaFlteGxJSGRsWVhSb1pYSWdkMlZpYzJsMFpTNGdWMjkxYkdRZ2VXOTFJR3hwYTJVZ2JXVWdkRzhpZlgwPSIsInAiOiJhYmNkZWZnaGlqayJ9GpDWtgAAAR8AAABLrcCUhws6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJZ2MzVm5aMlZ6ZENCemIyMWxJSE52ZFhKalpYTWdabTl5SUhWd0xYUnZMV1JoZEdVaWZYMD0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1In0EKYPnAAABCwAAAEs4oKXFCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUlnZDJWaGRHaGxjaUJwYm1admNtMWhkR2x2Ymo4aWZYMD0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1In2rYEZYAAAAqgAAAEu+u8BGCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTl6ZEc5d0lpd2lhVzVrWlhnaU9qQjkiLCJwIjoiYWJjZGVmZ2gifcwchfMAAAE0AAAASxvRipILOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pYldWemMyRm5aVjlrWld4MFlTSXNJbVJsYkhSaElqcDdJbk4wYjNCZmNtVmhjMjl1SWpvaVpXNWtYM1IxY200aUxDSnpkRzl3WDNObGNYVmxibU5sSWpwdWRXeHNmU3dpZFhOaFoyVWlPbnNpYjNWMGNIVjBYM1J2YTJWdWN5STZNVEUxZlgwPSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWCJ9PotWFgAAAVwAAABLspO2Hgs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2liV1Z6YzJGblpWOXpkRzl3SWl3aVlXMWhlbTl1TFdKbFpISnZZMnN0YVc1MmIyTmhkR2x2YmsxbGRISnBZM01pT25zaWFXNXdkWFJVYjJ0bGJrTnZkVzUwSWpveE1ERTVMQ0p2ZFhSd2RYUlViMnRsYmtOdmRXNTBJam94TVRVc0ltbHVkbTlqWVhScGIyNU1ZWFJsYm1ONUlqb3lOamN5TENKbWFYSnpkRUo1ZEdWTVlYUmxibU41SWpveE1UUTBmWDA9IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDRCJ9bAhYkw== + recorded_at: Tue, 25 Mar 2025 22:22:11 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_function_calling_claude-3-5-haiku_can_use_tools_without_parameters_with_bedrock.yml b/spec/fixtures/vcr_cassettes/chat_function_calling_claude-3-5-haiku_can_use_tools_without_parameters_with_bedrock.yml new file mode 100644 index 000000000..ab01ebf11 --- /dev/null +++ b/spec/fixtures/vcr_cassettes/chat_function_calling_claude-3-5-haiku_can_use_tools_without_parameters_with_bedrock.yml @@ -0,0 +1,123 @@ +--- +http_interactions: +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"What''s + the best language to learn?"}],"temperature":0.7,"max_tokens":4096,"tools":[{"name":"best_language_to_learn","description":"Gets + the best language to learn","input_schema":{"type":"object","properties":{},"required":[]}}]}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250326T150506Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - 5470b3b9e786d362a84d10e00f2ca7de6f684b36347b98361f45534636f69c1a + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250326/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=263824a7661419acc292499e27d1b7bbcc2603c05cb7d1a0ed4fdf98d90c1e00 + Content-Type: + - application/json + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 26 Mar 2025 15:05:07 GMT + Content-Type: + - application/json + Content-Length: + - '416' + Connection: + - keep-alive + X-Amzn-Requestid: + - 802ee619-9882-4513-875a-4a256afd98bb + X-Amzn-Bedrock-Invocation-Latency: + - '1115' + X-Amzn-Bedrock-Output-Token-Count: + - '56' + X-Amzn-Bedrock-Input-Token-Count: + - '327' + body: + encoding: UTF-8 + string: '{"id":"msg_bdrk_018qctpm5xnJFAhg8iGsyh9j","type":"message","role":"assistant","model":"claude-3-5-haiku-20241022","content":[{"type":"text","text":"I''ll + help you find out by using the best language to learn tool."},{"type":"tool_use","id":"toolu_bdrk_01TF3yhqhTcW4bJP3sM7xUs9","name":"best_language_to_learn","input":{}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":327,"output_tokens":56}}' + recorded_at: Wed, 26 Mar 2025 15:05:07 GMT +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"What''s + the best language to learn?"},{"role":"assistant","content":[{"type":"text","text":"I''ll + help you find out by using the best language to learn tool."},{"type":"tool_use","id":"toolu_bdrk_01TF3yhqhTcW4bJP3sM7xUs9","name":"best_language_to_learn","input":{}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_bdrk_01TF3yhqhTcW4bJP3sM7xUs9","content":"Ruby"}]}],"temperature":0.7,"max_tokens":4096,"tools":[{"name":"best_language_to_learn","description":"Gets + the best language to learn","input_schema":{"type":"object","properties":{},"required":[]}}]}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250326T150507Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - a738efc8beb12807ced753e348efc0b06c5046235adeb7968b61259e31610ad7 + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250326/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=8774c9b3e047112b6d546d2e74241e502a9aced903220c5cc6afc0e34008a24e + Content-Type: + - application/json + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 26 Mar 2025 15:05:13 GMT + Content-Type: + - application/json + Content-Length: + - '1127' + Connection: + - keep-alive + X-Amzn-Requestid: + - 41a8cb1f-0730-45b1-aa83-5f5c4bf52355 + X-Amzn-Bedrock-Invocation-Latency: + - '5256' + X-Amzn-Bedrock-Output-Token-Count: + - '189' + X-Amzn-Bedrock-Input-Token-Count: + - '395' + body: + encoding: UTF-8 + string: '{"id":"msg_bdrk_01EYFqfYHqwkAhndtoyQ47z6","type":"message","role":"assistant","model":"claude-3-5-haiku-20241022","content":[{"type":"text","text":"According + to the tool, Ruby is currently considered the best language to learn! Ruby + is a dynamic, object-oriented programming language known for its simplicity + and readability. It''s particularly popular for web development, especially + with the Ruby on Rails framework. \n\nSome reasons why Ruby might be a great + language to learn include:\n1. Easy to read and write syntax\n2. Strong community + support\n3. Versatile for web development\n4. Good for beginners due to its + intuitive nature\n5. Used in many startups and tech companies\n\nOf course, + the \"best\" language can depend on your specific goals, whether you''re interested + in web development, data science, mobile apps, or other programming areas. + But Ruby is certainly an excellent choice for many aspiring programmers!\n\nWould + you like to know more about Ruby or discuss why it might be a good language + for you to learn?"}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":395,"output_tokens":189}}' + recorded_at: Wed, 26 Mar 2025 15:05:13 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/chat_streaming_responses_claude-3-5-haiku_supports_streaming_responses_with_bedrock.yml b/spec/fixtures/vcr_cassettes/chat_streaming_responses_claude-3-5-haiku_supports_streaming_responses_with_bedrock.yml new file mode 100644 index 000000000..66379ea6b --- /dev/null +++ b/spec/fixtures/vcr_cassettes/chat_streaming_responses_claude-3-5-haiku_supports_streaming_responses_with_bedrock.yml @@ -0,0 +1,52 @@ +--- +http_interactions: +- request: + method: post + uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-5-haiku-20241022-v1:0/invoke-with-response-stream + body: + encoding: UTF-8 + string: '{"anthropic_version":"bedrock-2023-05-31","messages":[{"role":"user","content":"Count + from 1 to 3"}],"temperature":0.7,"max_tokens":4096}' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock-runtime.us-west-2.amazonaws.com + X-Amz-Date: + - 20250325T222417Z + X-Amz-Security-Token: + - "" + X-Amz-Content-Sha256: + - 7444002409115a1a6689bf49e7a862dedd9b424399df485afe093d31dbd9e873 + Authorization: + - AWS4-HMAC-SHA256 Credential=/20250325/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=a6817f7cca281c11cde92c54f945d0cf0f981b0323908e5f1a2926f8813603bb + Content-Type: + - application/json + Accept: + - application/vnd.amazon.eventstream + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 25 Mar 2025 22:23:36 GMT + Content-Type: + - application/vnd.amazon.eventstream + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Amzn-Requestid: + - 7711d91d-bcd2-40d4-bbab-05d98ac0a501 + X-Amzn-Bedrock-Content-Type: + - application/json + body: + encoding: ASCII-8BIT + string: !binary |- + AAAB1AAAAEszBU1NCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaWJXVnpjMkZuWlY5emRHRnlkQ0lzSW0xbGMzTmhaMlVpT25zaWFXUWlPaUp0YzJkZlltUnlhMTh3TVZCME1WTlVOMDVvWVRJM1pUUnBTM1ZUT1UxNVRuUWlMQ0owZVhCbElqb2liV1Z6YzJGblpTSXNJbkp2YkdVaU9pSmhjM05wYzNSaGJuUWlMQ0p0YjJSbGJDSTZJbU5zWVhWa1pTMHpMVFV0YUdGcGEzVXRNakF5TkRFd01qSWlMQ0pqYjI1MFpXNTBJanBiWFN3aWMzUnZjRjl5WldGemIyNGlPbTUxYkd3c0luTjBiM0JmYzJWeGRXVnVZMlVpT201MWJHd3NJblZ6WVdkbElqcDdJbWx1Y0hWMFgzUnZhMlZ1Y3lJNk1UVXNJbTkxZEhCMWRGOTBiMnRsYm5NaU9qRjlmWDA9IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6In3c/zoiAAAA/gAAAEtzKKlNCzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTl6ZEdGeWRDSXNJbWx1WkdWNElqb3dMQ0pqYjI1MFpXNTBYMkpzYjJOcklqcDdJblI1Y0dVaU9pSjBaWGgwSWl3aWRHVjRkQ0k2SWlKOWZRPT0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUYifZfw5TUAAAESAAAAS1VQUDYLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSklaWEpsSW4xOSIsInAiOiJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaIn1Pz3z6AAAA+wAAAEu7yCY9CzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTlrWld4MFlTSXNJbWx1WkdWNElqb3dMQ0prWld4MFlTSTZleUowZVhCbElqb2lkR1Y0ZEY5a1pXeDBZU0lzSW5SbGVIUWlPaUluY3lKOWZRPT0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkMifdlQ658AAAEWAAAAS6DQ9vYLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSWdZMjkxYm5ScGJtY2lmWDA9IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVViJ97gzgcgAAAOgAAABLnIjLbws6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lJZ1puSnZiU0F4SUNKOWZRPT0iLCJwIjoiYWIiffakF7gAAAETAAAAS2gweYYLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pWTI5dWRHVnVkRjlpYkc5amExOWtaV3gwWVNJc0ltbHVaR1Y0SWpvd0xDSmtaV3gwWVNJNmV5SjBlWEJsSWpvaWRHVjRkRjlrWld4MFlTSXNJblJsZUhRaU9pSjBieUF6T2lKOWZRPT0iLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWVyJ9pZ+XhwAAAPAAAABLzBgXLAs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lKY2JseHVNVnh1TWlKOWZRPT0iLCJwIjoiYWJjZGVmZ2hpaiJ9SijBugAAAPIAAABLtthETAs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2lZMjl1ZEdWdWRGOWliRzlqYTE5a1pXeDBZU0lzSW1sdVpHVjRJam93TENKa1pXeDBZU0k2ZXlKMGVYQmxJam9pZEdWNGRGOWtaV3gwWVNJc0luUmxlSFFpT2lKY2JqTWlmWDA9IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0In259nQVAAAA1gAAAEuCmc2ICzpldmVudC10eXBlBwAFY2h1bmsNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24NOm1lc3NhZ2UtdHlwZQcABWV2ZW50eyJieXRlcyI6ImV5SjBlWEJsSWpvaVkyOXVkR1Z1ZEY5aWJHOWphMTl6ZEc5d0lpd2lhVzVrWlhnaU9qQjkiLCJwIjoiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWiJ95uzNJQAAAScAAABLPJFnwAs6ZXZlbnQtdHlwZQcABWNodW5rDTpjb250ZW50LXR5cGUHABBhcHBsaWNhdGlvbi9qc29uDTptZXNzYWdlLXR5cGUHAAVldmVudHsiYnl0ZXMiOiJleUowZVhCbElqb2liV1Z6YzJGblpWOWtaV3gwWVNJc0ltUmxiSFJoSWpwN0luTjBiM0JmY21WaGMyOXVJam9pWlc1a1gzUjFjbTRpTENKemRHOXdYM05sY1hWbGJtTmxJanB1ZFd4c2ZTd2lkWE5oWjJVaU9uc2liM1YwY0hWMFgzUnZhMlZ1Y3lJNk1qQjlmUT09IiwicCI6ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSksifVv+HrwAAAE/AAAAS2wBu4MLOmV2ZW50LXR5cGUHAAVjaHVuaw06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbg06bWVzc2FnZS10eXBlBwAFZXZlbnR7ImJ5dGVzIjoiZXlKMGVYQmxJam9pYldWemMyRm5aVjl6ZEc5d0lpd2lZVzFoZW05dUxXSmxaSEp2WTJzdGFXNTJiMk5oZEdsdmJrMWxkSEpwWTNNaU9uc2lhVzV3ZFhSVWIydGxia052ZFc1MElqb3hOU3dpYjNWMGNIVjBWRzlyWlc1RGIzVnVkQ0k2TWpBc0ltbHVkbTlqWVhScGIyNU1ZWFJsYm1ONUlqb3hNVFExTENKbWFYSnpkRUo1ZEdWTVlYUmxibU41SWpvNE1qTjlmUT09IiwicCI6ImFiY2RlIn1l5ijz + recorded_at: Tue, 25 Mar 2025 22:24:19 GMT +recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/models_refresh_updates_models_and_returns_a_chainable_models_instance.yml b/spec/fixtures/vcr_cassettes/models_refresh_updates_models_and_returns_a_chainable_models_instance.yml index 0b01884f5..a33672469 100644 --- a/spec/fixtures/vcr_cassettes/models_refresh_updates_models_and_returns_a_chainable_models_instance.yml +++ b/spec/fixtures/vcr_cassettes/models_refresh_updates_models_and_returns_a_chainable_models_instance.yml @@ -1239,4 +1239,128 @@ http_interactions: encoding: ASCII-8BIT string: '{"object":"list","data":[{"id":"deepseek-chat","object":"model","owned_by":"deepseek"},{"id":"deepseek-reasoner","object":"model","owned_by":"deepseek"}]}' recorded_at: Tue, 25 Mar 2025 17:50:51 GMT +- request: + method: get + uri: https://bedrock.us-west-2.amazonaws.com/foundation-models + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock.us-west-2.amazonaws.com + X-Amz-Date: + - 20250325T171540Z + X-Amz-Security-Token: + - IQoJb3JpZ2luX2VjELH//////////wEaCXVzLXdlc3QtMiJGMEQCIDILea5LoQt0bejpnAvGlODePXWs+SVOVYKadYo/Rk9CAiBvj7jTOPExaq5kzi5J7Q2EI2OPjkGHwhnRvXZUSqD6LCqSAwgaEAYaDDIyMTg3MTkxNTQ2MyIMSNqSOazgocTuFlBsKu8C3Nbecj9HZFdBXZ7kaWtb3fByaNE9zYowsMzOb08Ugng8UL9qxzm5g0wT+NFvcJg4JvHNBlfxQyqhoqRAzSN8FAevZ2Pf59sReQbMAaKK0+CdIlH+begPkvTzwGvbj6CQhcRWkeD0UWRgLj1qpwJc2MhogI4CaSILeh/gkUC2fwtLaLK8KoXkrC+XWSvs/P+Qn5gF/YcwWYmlJjo1Y7zkaSRPD/V/SXrdEKCb7lHMkB9HgGSiV0kLg5y6KAcmBbG2HWd7S4qRu0Ko3lm3PIch5E4X7UDcxVLBtX0YErNR7vIRQvpbZ9itrjDqF1Wcckw26asVdC1UxbOSWrnAGqk8RFZrS17i4CP+XV+dQ3jD4/+ILYjKvXynqYA4TAwahL0104h7JCFELXmQOEwPmIPX4hmutyUEkkmfout1krQmzjE01ltNitPgVJzOI3On9YHKqBNp0aEgd6xC9frMseZ8Bb+d8B1Jx9oIBCVvH8RRtTDox4u/BjqnAVK1mPlee72ZUnkKg4jzL3LJL3OmDMBOEGSHmUoOTQ40feXeTlY01glfh7Cx3ExDxAUNIz96zwmhuVVSdwP9aGGsumlYsTJRz7wpDvgq8eGV+9JD9uG+55rtGsH8EzBS9Xw5bxJpBvmpIuRw6fKr7wBiCTTVyRR+Jl7JqGoQelm41v/mXIjzsO43zWUbwInRyFYzqxwmiPSHGwJJnn7eQriksmHxxh4i + X-Amz-Content-Sha256: + - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + Authorization: + - AWS4-HMAC-SHA256 Credential=ASIATHKEYYHDRJWE7TAB/20250325/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=e4a35761abf5be047cdd3c2b4383e1f3b30031acb59a6254960f1ef94b1a939a + Content-Type: + - application/json + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 25 Mar 2025 17:14:59 GMT + Content-Type: + - application/json + Content-Length: + - '45249' + Connection: + - keep-alive + X-Amzn-Requestid: + - '08c81519-bf5d-4c0f-8dad-e1fe0e12c7fa' + body: + encoding: UTF-8 + string: '{"modelSummaries":[{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-tg1-large","modelId":"amazon.titan-tg1-large","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Text Large","outputModalities":["TEXT"],"providerName":"Amazon","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-embed-g1-text-02","modelId":"amazon.titan-embed-g1-text-02","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Text Embeddings v2","outputModalities":["EMBEDDING"],"providerName":"Amazon","responseStreamingSupported":null},{"customizationsSupported":["FINE_TUNING","CONTINUED_PRE_TRAINING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-text-lite-v1:0:4k","modelId":"amazon.titan-text-lite-v1:0:4k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Text G1 - Lite","outputModalities":["TEXT"],"providerName":"Amazon","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-text-lite-v1","modelId":"amazon.titan-text-lite-v1","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Text G1 - Lite","outputModalities":["TEXT"],"providerName":"Amazon","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING","CONTINUED_PRE_TRAINING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-text-express-v1:0:8k","modelId":"amazon.titan-text-express-v1:0:8k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Text G1 - Express","outputModalities":["TEXT"],"providerName":"Amazon","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-text-express-v1","modelId":"amazon.titan-text-express-v1","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Text G1 - Express","outputModalities":["TEXT"],"providerName":"Amazon","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":true},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT","IMAGE","VIDEO"],"intelligentPromptRouting":{"isSupported":true},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.nova-pro-v1:0","modelId":"amazon.nova-pro-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Nova + Pro","outputModalities":["TEXT"],"providerName":"Amazon","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":true},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT","IMAGE","VIDEO"],"intelligentPromptRouting":{"isSupported":true},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.nova-lite-v1:0","modelId":"amazon.nova-lite-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Nova + Lite","outputModalities":["TEXT"],"providerName":"Amazon","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":true},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.nova-micro-v1:0","modelId":"amazon.nova-micro-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Nova + Micro","outputModalities":["TEXT"],"providerName":"Amazon","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-embed-text-v1:2:8k","modelId":"amazon.titan-embed-text-v1:2:8k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Embeddings G1 - Text","outputModalities":["EMBEDDING"],"providerName":"Amazon","responseStreamingSupported":false},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-embed-text-v1","modelId":"amazon.titan-embed-text-v1","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Embeddings G1 - Text","outputModalities":["EMBEDDING"],"providerName":"Amazon","responseStreamingSupported":false},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-embed-text-v2:0","modelId":"amazon.titan-embed-text-v2:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Text Embeddings V2","outputModalities":["EMBEDDING"],"providerName":"Amazon","responseStreamingSupported":false},{"customizationsSupported":["FINE_TUNING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-embed-image-v1:0","modelId":"amazon.titan-embed-image-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Multimodal Embeddings G1","outputModalities":["EMBEDDING"],"providerName":"Amazon","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-embed-image-v1","modelId":"amazon.titan-embed-image-v1","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Multimodal Embeddings G1","outputModalities":["EMBEDDING"],"providerName":"Amazon","responseStreamingSupported":null},{"customizationsSupported":["FINE_TUNING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-image-generator-v1:0","modelId":"amazon.titan-image-generator-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Image Generator G1","outputModalities":["IMAGE"],"providerName":"Amazon","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-image-generator-v1","modelId":"amazon.titan-image-generator-v1","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Image Generator G1","outputModalities":["IMAGE"],"providerName":"Amazon","responseStreamingSupported":null},{"customizationsSupported":["FINE_TUNING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED","ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-image-generator-v2:0","modelId":"amazon.titan-image-generator-v2:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Image Generator G1 v2","outputModalities":["IMAGE"],"providerName":"Amazon","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.rerank-v1:0","modelId":"amazon.rerank-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Rerank + 1.0","outputModalities":["TEXT"],"providerName":"Amazon","responseStreamingSupported":false},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/stability.stable-diffusion-xl-v1:0","modelId":"stability.stable-diffusion-xl-v1:0","modelLifecycle":{"status":"LEGACY"},"modelName":"SDXL + 1.0","outputModalities":["IMAGE"],"providerName":"Stability AI","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/stability.stable-diffusion-xl-v1","modelId":"stability.stable-diffusion-xl-v1","modelLifecycle":{"status":"LEGACY"},"modelName":"SDXL + 1.0","outputModalities":["IMAGE"],"providerName":"Stability AI","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/stability.sd3-large-v1:0","modelId":"stability.sd3-large-v1:0","modelLifecycle":{"status":"LEGACY"},"modelName":"SD3 + Large 1.0","outputModalities":["IMAGE"],"providerName":"Stability AI","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/stability.sd3-5-large-v1:0","modelId":"stability.sd3-5-large-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Stable + Diffusion 3.5 Large","outputModalities":["IMAGE"],"providerName":"Stability + AI","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/stability.stable-image-core-v1:0","modelId":"stability.stable-image-core-v1:0","modelLifecycle":{"status":"LEGACY"},"modelName":"Stable + Image Core 1.0","outputModalities":["IMAGE"],"providerName":"Stability AI","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/stability.stable-image-core-v1:1","modelId":"stability.stable-image-core-v1:1","modelLifecycle":{"status":"ACTIVE"},"modelName":"Stable + Image Core 1.0","outputModalities":["IMAGE"],"providerName":"Stability AI","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/stability.stable-image-ultra-v1:0","modelId":"stability.stable-image-ultra-v1:0","modelLifecycle":{"status":"LEGACY"},"modelName":"Stable + Image Ultra 1.0","outputModalities":["IMAGE"],"providerName":"Stability AI","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/stability.stable-image-ultra-v1:1","modelId":"stability.stable-image-ultra-v1:1","modelLifecycle":{"status":"ACTIVE"},"modelName":"Stable + Image Ultra 1.0","outputModalities":["IMAGE"],"providerName":"Stability AI","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":true},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0:18k","modelId":"anthropic.claude-3-5-sonnet-20241022-v2:0:18k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.5 Sonnet v2","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":true},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0:51k","modelId":"anthropic.claude-3-5-sonnet-20241022-v2:0:51k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.5 Sonnet v2","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":true},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0:200k","modelId":"anthropic.claude-3-5-sonnet-20241022-v2:0:200k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.5 Sonnet v2","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":true},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":true},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0","modelId":"anthropic.claude-3-5-sonnet-20241022-v2:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.5 Sonnet v2","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":true},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-7-sonnet-20250219-v1:0","modelId":"anthropic.claude-3-7-sonnet-20250219-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.7 Sonnet","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":true},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":true},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-haiku-20241022-v1:0","modelId":"anthropic.claude-3-5-haiku-20241022-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.5 Haiku","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-instant-v1:2:100k","modelId":"anthropic.claude-instant-v1:2:100k","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude + Instant","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-instant-v1","modelId":"anthropic.claude-instant-v1","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude + Instant","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-v2:0:18k","modelId":"anthropic.claude-v2:0:18k","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-v2:0:100k","modelId":"anthropic.claude-v2:0:100k","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-v2:1:18k","modelId":"anthropic.claude-v2:1:18k","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-v2:1:200k","modelId":"anthropic.claude-v2:1:200k","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-v2:1","modelId":"anthropic.claude-v2:1","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-v2","modelId":"anthropic.claude-v2","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0:28k","modelId":"anthropic.claude-3-sonnet-20240229-v1:0:28k","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude + 3 Sonnet","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0:200k","modelId":"anthropic.claude-3-sonnet-20240229-v1:0:200k","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude + 3 Sonnet","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0","modelId":"anthropic.claude-3-sonnet-20240229-v1:0","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude + 3 Sonnet","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-haiku-20240307-v1:0:48k","modelId":"anthropic.claude-3-haiku-20240307-v1:0:48k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3 Haiku","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING","DISTILLATION"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-haiku-20240307-v1:0:200k","modelId":"anthropic.claude-3-haiku-20240307-v1:0:200k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3 Haiku","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":true},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-haiku-20240307-v1:0","modelId":"anthropic.claude-3-haiku-20240307-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3 Haiku","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-opus-20240229-v1:0:12k","modelId":"anthropic.claude-3-opus-20240229-v1:0:12k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3 Opus","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-opus-20240229-v1:0:28k","modelId":"anthropic.claude-3-opus-20240229-v1:0:28k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3 Opus","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-opus-20240229-v1:0:200k","modelId":"anthropic.claude-3-opus-20240229-v1:0:200k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3 Opus","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-opus-20240229-v1:0","modelId":"anthropic.claude-3-opus-20240229-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3 Opus","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0:18k","modelId":"anthropic.claude-3-5-sonnet-20240620-v1:0:18k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.5 Sonnet","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0:51k","modelId":"anthropic.claude-3-5-sonnet-20240620-v1:0:51k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.5 Sonnet","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0:200k","modelId":"anthropic.claude-3-5-sonnet-20240620-v1:0:200k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.5 Sonnet","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND","INFERENCE_PROFILE"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":true},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0","modelId":"anthropic.claude-3-5-sonnet-20240620-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.5 Sonnet","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.command-text-v14:7:4k","modelId":"cohere.command-text-v14:7:4k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Command","outputModalities":["TEXT"],"providerName":"Cohere","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.command-text-v14","modelId":"cohere.command-text-v14","modelLifecycle":{"status":"ACTIVE"},"modelName":"Command","outputModalities":["TEXT"],"providerName":"Cohere","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.command-r-v1:0","modelId":"cohere.command-r-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Command + R","outputModalities":["TEXT"],"providerName":"Cohere","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.command-r-plus-v1:0","modelId":"cohere.command-r-plus-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Command + R+","outputModalities":["TEXT"],"providerName":"Cohere","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.command-light-text-v14:7:4k","modelId":"cohere.command-light-text-v14:7:4k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Command + Light","outputModalities":["TEXT"],"providerName":"Cohere","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.command-light-text-v14","modelId":"cohere.command-light-text-v14","modelLifecycle":{"status":"ACTIVE"},"modelName":"Command + Light","outputModalities":["TEXT"],"providerName":"Cohere","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.embed-english-v3:0:512","modelId":"cohere.embed-english-v3:0:512","modelLifecycle":{"status":"ACTIVE"},"modelName":"Embed + English","outputModalities":["EMBEDDING"],"providerName":"Cohere","responseStreamingSupported":false},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.embed-english-v3","modelId":"cohere.embed-english-v3","modelLifecycle":{"status":"ACTIVE"},"modelName":"Embed + English","outputModalities":["EMBEDDING"],"providerName":"Cohere","responseStreamingSupported":false},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.embed-multilingual-v3:0:512","modelId":"cohere.embed-multilingual-v3:0:512","modelLifecycle":{"status":"ACTIVE"},"modelName":"Embed + Multilingual","outputModalities":["EMBEDDING"],"providerName":"Cohere","responseStreamingSupported":false},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.embed-multilingual-v3","modelId":"cohere.embed-multilingual-v3","modelLifecycle":{"status":"ACTIVE"},"modelName":"Embed + Multilingual","outputModalities":["EMBEDDING"],"providerName":"Cohere","responseStreamingSupported":false},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.rerank-v3-5:0","modelId":"cohere.rerank-v3-5:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Rerank + 3.5","outputModalities":["TEXT"],"providerName":"Cohere","responseStreamingSupported":false},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/deepseek.r1-v1:0","modelId":"deepseek.r1-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"DeepSeek-R1","outputModalities":["TEXT"],"providerName":"DeepSeek","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-8b-instruct-v1:0","modelId":"meta.llama3-8b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3 8B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-70b-instruct-v1:0","modelId":"meta.llama3-70b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3 70B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING","DISTILLATION"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-1-8b-instruct-v1:0:128k","modelId":"meta.llama3-1-8b-instruct-v1:0:128k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.1 8B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":true},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-1-8b-instruct-v1:0","modelId":"meta.llama3-1-8b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.1 8B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING","DISTILLATION"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-1-70b-instruct-v1:0:128k","modelId":"meta.llama3-1-70b-instruct-v1:0:128k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.1 70B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":true},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-1-70b-instruct-v1:0","modelId":"meta.llama3-1-70b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.1 70B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-1-405b-instruct-v1:0","modelId":"meta.llama3-1-405b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.1 405B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-2-11b-instruct-v1:0:128k","modelId":"meta.llama3-2-11b-instruct-v1:0:128k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.2 11B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":true},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-2-11b-instruct-v1:0","modelId":"meta.llama3-2-11b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.2 11B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-2-90b-instruct-v1:0:128k","modelId":"meta.llama3-2-90b-instruct-v1:0:128k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.2 90B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":true},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-2-90b-instruct-v1:0","modelId":"meta.llama3-2-90b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.2 90B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-2-1b-instruct-v1:0:128k","modelId":"meta.llama3-2-1b-instruct-v1:0:128k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.2 1B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-2-1b-instruct-v1:0","modelId":"meta.llama3-2-1b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.2 1B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-2-3b-instruct-v1:0:128k","modelId":"meta.llama3-2-3b-instruct-v1:0:128k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.2 3B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-2-3b-instruct-v1:0","modelId":"meta.llama3-2-3b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.2 3B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":true},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-3-70b-instruct-v1:0","modelId":"meta.llama3-3-70b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.3 70B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/mistral.mistral-7b-instruct-v0:2","modelId":"mistral.mistral-7b-instruct-v0:2","modelLifecycle":{"status":"ACTIVE"},"modelName":"Mistral + 7B Instruct","outputModalities":["TEXT"],"providerName":"Mistral AI","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/mistral.mixtral-8x7b-instruct-v0:1","modelId":"mistral.mixtral-8x7b-instruct-v0:1","modelLifecycle":{"status":"ACTIVE"},"modelName":"Mixtral + 8x7B Instruct","outputModalities":["TEXT"],"providerName":"Mistral AI","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/mistral.mistral-large-2402-v1:0","modelId":"mistral.mistral-large-2402-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Mistral + Large (24.02)","outputModalities":["TEXT"],"providerName":"Mistral AI","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/mistral.mistral-large-2407-v1:0","modelId":"mistral.mistral-large-2407-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Mistral + Large (24.07)","outputModalities":["TEXT"],"providerName":"Mistral AI","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/luma.ray-v2:0","modelId":"luma.ray-v2:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Ray + v2","outputModalities":["VIDEO"],"providerName":"Luma AI","responseStreamingSupported":false}]}' + recorded_at: Tue, 25 Mar 2025 17:15:40 GMT recorded_with: VCR 6.3.1 diff --git a/spec/fixtures/vcr_cassettes/models_refresh_works_as_a_class_method_too.yml b/spec/fixtures/vcr_cassettes/models_refresh_works_as_a_class_method_too.yml index d2efc0131..d4d82924a 100644 --- a/spec/fixtures/vcr_cassettes/models_refresh_works_as_a_class_method_too.yml +++ b/spec/fixtures/vcr_cassettes/models_refresh_works_as_a_class_method_too.yml @@ -1239,4 +1239,128 @@ http_interactions: encoding: ASCII-8BIT string: '{"object":"list","data":[{"id":"deepseek-chat","object":"model","owned_by":"deepseek"},{"id":"deepseek-reasoner","object":"model","owned_by":"deepseek"}]}' recorded_at: Tue, 25 Mar 2025 17:50:52 GMT +- request: + method: get + uri: https://bedrock.us-west-2.amazonaws.com/foundation-models + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Faraday v2.12.2 + Host: + - bedrock.us-west-2.amazonaws.com + X-Amz-Date: + - 20250325T171540Z + X-Amz-Security-Token: + - IQoJb3JpZ2luX2VjELH//////////wEaCXVzLXdlc3QtMiJGMEQCIDILea5LoQt0bejpnAvGlODePXWs+SVOVYKadYo/Rk9CAiBvj7jTOPExaq5kzi5J7Q2EI2OPjkGHwhnRvXZUSqD6LCqSAwgaEAYaDDIyMTg3MTkxNTQ2MyIMSNqSOazgocTuFlBsKu8C3Nbecj9HZFdBXZ7kaWtb3fByaNE9zYowsMzOb08Ugng8UL9qxzm5g0wT+NFvcJg4JvHNBlfxQyqhoqRAzSN8FAevZ2Pf59sReQbMAaKK0+CdIlH+begPkvTzwGvbj6CQhcRWkeD0UWRgLj1qpwJc2MhogI4CaSILeh/gkUC2fwtLaLK8KoXkrC+XWSvs/P+Qn5gF/YcwWYmlJjo1Y7zkaSRPD/V/SXrdEKCb7lHMkB9HgGSiV0kLg5y6KAcmBbG2HWd7S4qRu0Ko3lm3PIch5E4X7UDcxVLBtX0YErNR7vIRQvpbZ9itrjDqF1Wcckw26asVdC1UxbOSWrnAGqk8RFZrS17i4CP+XV+dQ3jD4/+ILYjKvXynqYA4TAwahL0104h7JCFELXmQOEwPmIPX4hmutyUEkkmfout1krQmzjE01ltNitPgVJzOI3On9YHKqBNp0aEgd6xC9frMseZ8Bb+d8B1Jx9oIBCVvH8RRtTDox4u/BjqnAVK1mPlee72ZUnkKg4jzL3LJL3OmDMBOEGSHmUoOTQ40feXeTlY01glfh7Cx3ExDxAUNIz96zwmhuVVSdwP9aGGsumlYsTJRz7wpDvgq8eGV+9JD9uG+55rtGsH8EzBS9Xw5bxJpBvmpIuRw6fKr7wBiCTTVyRR+Jl7JqGoQelm41v/mXIjzsO43zWUbwInRyFYzqxwmiPSHGwJJnn7eQriksmHxxh4i + X-Amz-Content-Sha256: + - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + Authorization: + - AWS4-HMAC-SHA256 Credential=ASIATHKEYYHDRJWE7TAB/20250325/us-west-2/bedrock/aws4_request, + SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=e4a35761abf5be047cdd3c2b4383e1f3b30031acb59a6254960f1ef94b1a939a + Content-Type: + - application/json + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 25 Mar 2025 17:14:59 GMT + Content-Type: + - application/json + Content-Length: + - '45236' + Connection: + - keep-alive + X-Amzn-Requestid: + - 1d0095b0-65f3-4c04-82e3-8e4af99316cd + body: + encoding: UTF-8 + string: '{"modelSummaries":[{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-tg1-large","modelId":"amazon.titan-tg1-large","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Text Large","outputModalities":["TEXT"],"providerName":"Amazon","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-embed-g1-text-02","modelId":"amazon.titan-embed-g1-text-02","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Text Embeddings v2","outputModalities":["EMBEDDING"],"providerName":"Amazon","responseStreamingSupported":null},{"customizationsSupported":["FINE_TUNING","CONTINUED_PRE_TRAINING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-text-lite-v1:0:4k","modelId":"amazon.titan-text-lite-v1:0:4k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Text G1 - Lite","outputModalities":["TEXT"],"providerName":"Amazon","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-text-lite-v1","modelId":"amazon.titan-text-lite-v1","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Text G1 - Lite","outputModalities":["TEXT"],"providerName":"Amazon","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING","CONTINUED_PRE_TRAINING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-text-express-v1:0:8k","modelId":"amazon.titan-text-express-v1:0:8k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Text G1 - Express","outputModalities":["TEXT"],"providerName":"Amazon","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-text-express-v1","modelId":"amazon.titan-text-express-v1","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Text G1 - Express","outputModalities":["TEXT"],"providerName":"Amazon","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":true},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT","IMAGE","VIDEO"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.nova-pro-v1:0","modelId":"amazon.nova-pro-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Nova + Pro","outputModalities":["TEXT"],"providerName":"Amazon","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":true},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT","IMAGE","VIDEO"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.nova-lite-v1:0","modelId":"amazon.nova-lite-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Nova + Lite","outputModalities":["TEXT"],"providerName":"Amazon","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":true},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.nova-micro-v1:0","modelId":"amazon.nova-micro-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Nova + Micro","outputModalities":["TEXT"],"providerName":"Amazon","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-embed-text-v1:2:8k","modelId":"amazon.titan-embed-text-v1:2:8k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Embeddings G1 - Text","outputModalities":["EMBEDDING"],"providerName":"Amazon","responseStreamingSupported":false},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-embed-text-v1","modelId":"amazon.titan-embed-text-v1","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Embeddings G1 - Text","outputModalities":["EMBEDDING"],"providerName":"Amazon","responseStreamingSupported":false},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-embed-text-v2:0","modelId":"amazon.titan-embed-text-v2:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Text Embeddings V2","outputModalities":["EMBEDDING"],"providerName":"Amazon","responseStreamingSupported":false},{"customizationsSupported":["FINE_TUNING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-embed-image-v1:0","modelId":"amazon.titan-embed-image-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Multimodal Embeddings G1","outputModalities":["EMBEDDING"],"providerName":"Amazon","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-embed-image-v1","modelId":"amazon.titan-embed-image-v1","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Multimodal Embeddings G1","outputModalities":["EMBEDDING"],"providerName":"Amazon","responseStreamingSupported":null},{"customizationsSupported":["FINE_TUNING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-image-generator-v1:0","modelId":"amazon.titan-image-generator-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Image Generator G1","outputModalities":["IMAGE"],"providerName":"Amazon","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-image-generator-v1","modelId":"amazon.titan-image-generator-v1","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Image Generator G1","outputModalities":["IMAGE"],"providerName":"Amazon","responseStreamingSupported":null},{"customizationsSupported":["FINE_TUNING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED","ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.titan-image-generator-v2:0","modelId":"amazon.titan-image-generator-v2:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Titan + Image Generator G1 v2","outputModalities":["IMAGE"],"providerName":"Amazon","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/amazon.rerank-v1:0","modelId":"amazon.rerank-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Rerank + 1.0","outputModalities":["TEXT"],"providerName":"Amazon","responseStreamingSupported":false},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/stability.stable-diffusion-xl-v1:0","modelId":"stability.stable-diffusion-xl-v1:0","modelLifecycle":{"status":"LEGACY"},"modelName":"SDXL + 1.0","outputModalities":["IMAGE"],"providerName":"Stability AI","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/stability.stable-diffusion-xl-v1","modelId":"stability.stable-diffusion-xl-v1","modelLifecycle":{"status":"LEGACY"},"modelName":"SDXL + 1.0","outputModalities":["IMAGE"],"providerName":"Stability AI","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/stability.sd3-large-v1:0","modelId":"stability.sd3-large-v1:0","modelLifecycle":{"status":"LEGACY"},"modelName":"SD3 + Large 1.0","outputModalities":["IMAGE"],"providerName":"Stability AI","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/stability.sd3-5-large-v1:0","modelId":"stability.sd3-5-large-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Stable + Diffusion 3.5 Large","outputModalities":["IMAGE"],"providerName":"Stability + AI","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/stability.stable-image-core-v1:0","modelId":"stability.stable-image-core-v1:0","modelLifecycle":{"status":"LEGACY"},"modelName":"Stable + Image Core 1.0","outputModalities":["IMAGE"],"providerName":"Stability AI","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/stability.stable-image-core-v1:1","modelId":"stability.stable-image-core-v1:1","modelLifecycle":{"status":"ACTIVE"},"modelName":"Stable + Image Core 1.0","outputModalities":["IMAGE"],"providerName":"Stability AI","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/stability.stable-image-ultra-v1:0","modelId":"stability.stable-image-ultra-v1:0","modelLifecycle":{"status":"LEGACY"},"modelName":"Stable + Image Ultra 1.0","outputModalities":["IMAGE"],"providerName":"Stability AI","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/stability.stable-image-ultra-v1:1","modelId":"stability.stable-image-ultra-v1:1","modelLifecycle":{"status":"ACTIVE"},"modelName":"Stable + Image Ultra 1.0","outputModalities":["IMAGE"],"providerName":"Stability AI","responseStreamingSupported":null},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":true},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0:18k","modelId":"anthropic.claude-3-5-sonnet-20241022-v2:0:18k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.5 Sonnet v2","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":true},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0:51k","modelId":"anthropic.claude-3-5-sonnet-20241022-v2:0:51k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.5 Sonnet v2","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":true},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0:200k","modelId":"anthropic.claude-3-5-sonnet-20241022-v2:0:200k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.5 Sonnet v2","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":true},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0","modelId":"anthropic.claude-3-5-sonnet-20241022-v2:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.5 Sonnet v2","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":true},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-7-sonnet-20250219-v1:0","modelId":"anthropic.claude-3-7-sonnet-20250219-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.7 Sonnet","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":true},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-haiku-20241022-v1:0","modelId":"anthropic.claude-3-5-haiku-20241022-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.5 Haiku","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-instant-v1:2:100k","modelId":"anthropic.claude-instant-v1:2:100k","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude + Instant","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-instant-v1","modelId":"anthropic.claude-instant-v1","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude + Instant","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-v2:0:18k","modelId":"anthropic.claude-v2:0:18k","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-v2:0:100k","modelId":"anthropic.claude-v2:0:100k","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-v2:1:18k","modelId":"anthropic.claude-v2:1:18k","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-v2:1:200k","modelId":"anthropic.claude-v2:1:200k","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-v2:1","modelId":"anthropic.claude-v2:1","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-v2","modelId":"anthropic.claude-v2","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0:28k","modelId":"anthropic.claude-3-sonnet-20240229-v1:0:28k","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude + 3 Sonnet","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0:200k","modelId":"anthropic.claude-3-sonnet-20240229-v1:0:200k","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude + 3 Sonnet","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0","modelId":"anthropic.claude-3-sonnet-20240229-v1:0","modelLifecycle":{"status":"LEGACY"},"modelName":"Claude + 3 Sonnet","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-haiku-20240307-v1:0:48k","modelId":"anthropic.claude-3-haiku-20240307-v1:0:48k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3 Haiku","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING","DISTILLATION"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-haiku-20240307-v1:0:200k","modelId":"anthropic.claude-3-haiku-20240307-v1:0:200k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3 Haiku","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":true},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-haiku-20240307-v1:0","modelId":"anthropic.claude-3-haiku-20240307-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3 Haiku","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-opus-20240229-v1:0:12k","modelId":"anthropic.claude-3-opus-20240229-v1:0:12k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3 Opus","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-opus-20240229-v1:0:28k","modelId":"anthropic.claude-3-opus-20240229-v1:0:28k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3 Opus","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-opus-20240229-v1:0:200k","modelId":"anthropic.claude-3-opus-20240229-v1:0:200k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3 Opus","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-opus-20240229-v1:0","modelId":"anthropic.claude-3-opus-20240229-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3 Opus","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0:18k","modelId":"anthropic.claude-3-5-sonnet-20240620-v1:0:18k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.5 Sonnet","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0:51k","modelId":"anthropic.claude-3-5-sonnet-20240620-v1:0:51k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.5 Sonnet","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0:200k","modelId":"anthropic.claude-3-5-sonnet-20240620-v1:0:200k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.5 Sonnet","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":true},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0","modelId":"anthropic.claude-3-5-sonnet-20240620-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Claude + 3.5 Sonnet","outputModalities":["TEXT"],"providerName":"Anthropic","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.command-text-v14:7:4k","modelId":"cohere.command-text-v14:7:4k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Command","outputModalities":["TEXT"],"providerName":"Cohere","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.command-text-v14","modelId":"cohere.command-text-v14","modelLifecycle":{"status":"ACTIVE"},"modelName":"Command","outputModalities":["TEXT"],"providerName":"Cohere","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.command-r-v1:0","modelId":"cohere.command-r-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Command + R","outputModalities":["TEXT"],"providerName":"Cohere","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.command-r-plus-v1:0","modelId":"cohere.command-r-plus-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Command + R+","outputModalities":["TEXT"],"providerName":"Cohere","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.command-light-text-v14:7:4k","modelId":"cohere.command-light-text-v14:7:4k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Command + Light","outputModalities":["TEXT"],"providerName":"Cohere","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.command-light-text-v14","modelId":"cohere.command-light-text-v14","modelLifecycle":{"status":"ACTIVE"},"modelName":"Command + Light","outputModalities":["TEXT"],"providerName":"Cohere","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.embed-english-v3:0:512","modelId":"cohere.embed-english-v3:0:512","modelLifecycle":{"status":"ACTIVE"},"modelName":"Embed + English","outputModalities":["EMBEDDING"],"providerName":"Cohere","responseStreamingSupported":false},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.embed-english-v3","modelId":"cohere.embed-english-v3","modelLifecycle":{"status":"ACTIVE"},"modelName":"Embed + English","outputModalities":["EMBEDDING"],"providerName":"Cohere","responseStreamingSupported":false},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.embed-multilingual-v3:0:512","modelId":"cohere.embed-multilingual-v3:0:512","modelLifecycle":{"status":"ACTIVE"},"modelName":"Embed + Multilingual","outputModalities":["EMBEDDING"],"providerName":"Cohere","responseStreamingSupported":false},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.embed-multilingual-v3","modelId":"cohere.embed-multilingual-v3","modelLifecycle":{"status":"ACTIVE"},"modelName":"Embed + Multilingual","outputModalities":["EMBEDDING"],"providerName":"Cohere","responseStreamingSupported":false},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/cohere.rerank-v3-5:0","modelId":"cohere.rerank-v3-5:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Rerank + 3.5","outputModalities":["TEXT"],"providerName":"Cohere","responseStreamingSupported":false},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/deepseek.r1-v1:0","modelId":"deepseek.r1-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"DeepSeek-R1","outputModalities":["TEXT"],"providerName":"DeepSeek","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-8b-instruct-v1:0","modelId":"meta.llama3-8b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3 8B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-70b-instruct-v1:0","modelId":"meta.llama3-70b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3 70B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING","DISTILLATION"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-1-8b-instruct-v1:0:128k","modelId":"meta.llama3-1-8b-instruct-v1:0:128k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.1 8B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":true},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-1-8b-instruct-v1:0","modelId":"meta.llama3-1-8b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.1 8B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING","DISTILLATION"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-1-70b-instruct-v1:0:128k","modelId":"meta.llama3-1-70b-instruct-v1:0:128k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.1 70B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":true},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-1-70b-instruct-v1:0","modelId":"meta.llama3-1-70b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.1 70B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-1-405b-instruct-v1:0","modelId":"meta.llama3-1-405b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.1 405B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-2-11b-instruct-v1:0:128k","modelId":"meta.llama3-2-11b-instruct-v1:0:128k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.2 11B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-2-11b-instruct-v1:0","modelId":"meta.llama3-2-11b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.2 11B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-2-90b-instruct-v1:0:128k","modelId":"meta.llama3-2-90b-instruct-v1:0:128k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.2 90B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT","IMAGE"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-2-90b-instruct-v1:0","modelId":"meta.llama3-2-90b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.2 90B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-2-1b-instruct-v1:0:128k","modelId":"meta.llama3-2-1b-instruct-v1:0:128k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.2 1B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-2-1b-instruct-v1:0","modelId":"meta.llama3-2-1b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.2 1B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":["FINE_TUNING"],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["PROVISIONED"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-2-3b-instruct-v1:0:128k","modelId":"meta.llama3-2-3b-instruct-v1:0:128k","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.2 3B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-2-3b-instruct-v1:0","modelId":"meta.llama3-2-3b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.2 3B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["INFERENCE_PROFILE"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/meta.llama3-3-70b-instruct-v1:0","modelId":"meta.llama3-3-70b-instruct-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Llama + 3.3 70B Instruct","outputModalities":["TEXT"],"providerName":"Meta","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/mistral.mistral-7b-instruct-v0:2","modelId":"mistral.mistral-7b-instruct-v0:2","modelLifecycle":{"status":"ACTIVE"},"modelName":"Mistral + 7B Instruct","outputModalities":["TEXT"],"providerName":"Mistral AI","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/mistral.mixtral-8x7b-instruct-v0:1","modelId":"mistral.mixtral-8x7b-instruct-v0:1","modelLifecycle":{"status":"ACTIVE"},"modelName":"Mixtral + 8x7B Instruct","outputModalities":["TEXT"],"providerName":"Mistral AI","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/mistral.mistral-large-2402-v1:0","modelId":"mistral.mistral-large-2402-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Mistral + Large (24.02)","outputModalities":["TEXT"],"providerName":"Mistral AI","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":true,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/mistral.mistral-large-2407-v1:0","modelId":"mistral.mistral-large-2407-v1:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Mistral + Large (24.07)","outputModalities":["TEXT"],"providerName":"Mistral AI","responseStreamingSupported":true},{"customizationsSupported":[],"explicitPromptCaching":{"isSupported":false},"guardrailsSupported":false,"inferenceTypesSupported":["ON_DEMAND"],"inputModalities":["TEXT"],"intelligentPromptRouting":{"isSupported":false},"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/luma.ray-v2:0","modelId":"luma.ray-v2:0","modelLifecycle":{"status":"ACTIVE"},"modelName":"Ray + v2","outputModalities":["VIDEO"],"providerName":"Luma AI","responseStreamingSupported":false}]}' + recorded_at: Tue, 25 Mar 2025 17:15:41 GMT recorded_with: VCR 6.3.1 diff --git a/spec/ruby_llm/chat_spec.rb b/spec/ruby_llm/chat_spec.rb index 7ced4f959..cd5583aba 100644 --- a/spec/ruby_llm/chat_spec.rb +++ b/spec/ruby_llm/chat_spec.rb @@ -8,13 +8,15 @@ describe 'basic chat functionality' do [ - 'claude-3-5-haiku-20241022', - 'gemini-2.0-flash', - 'deepseek-chat', - 'gpt-4o-mini' - ].each do |model| - it "#{model} can have a basic conversation" do # rubocop:disable RSpec/ExampleLength,RSpec/MultipleExpectations - chat = RubyLLM.chat(model: model) + ['claude-3-5-haiku-20241022', nil], + ['gemini-2.0-flash', nil], + ['deepseek-chat', nil], + ['gpt-4o-mini', nil], + %w[claude-3-5-haiku bedrock] + ].each do |model, provider| + provider_suffix = provider ? " with #{provider}" : '' + it "#{model} can have a basic conversation#{provider_suffix}" do # rubocop:disable RSpec/ExampleLength,RSpec/MultipleExpectations + chat = RubyLLM.chat(model: model, provider: provider) response = chat.ask("What's 2 + 2?") expect(response.content).to include('4') @@ -23,8 +25,8 @@ expect(response.output_tokens).to be_positive end - it "#{model} can handle multi-turn conversations" do # rubocop:disable RSpec/MultipleExpectations - chat = RubyLLM.chat(model: model) + it "#{model} can handle multi-turn conversations#{provider_suffix}" do # rubocop:disable RSpec/MultipleExpectations + chat = RubyLLM.chat(model: model, provider: provider) first = chat.ask("Who was Ruby's creator?") expect(first.content).to include('Matz') @@ -33,5 +35,24 @@ expect(followup.content).to include('199') end end + + it 'claude-3-5-haiku can handle system messages with bedrock' do # rubocop:disable RSpec/ExampleLength,RSpec/MultipleExpectations + chat = RubyLLM.chat(model: 'claude-3-5-haiku', provider: 'bedrock') + + # Add a system message + chat.add_message(role: :system, content: 'You are a helpful math tutor who always shows your work.') + + response = chat.ask('What is 15 + 27?') + expect(response.content).to include('42') + expect(response.content).to match(/step|work|process/i) # Should show work as instructed + + # Add another system message + chat.add_message(role: :system, content: 'Always include a fun fact about numbers in your response.') + + response = chat.ask('What is 25 * 4?') + expect(response.content).to include('100') + expect(response.content).to match(/step|work|process/i) # Should still show work + expect(response.content).to match(/fact|interesting|did you know/i) # Should include a fun fact + end end end diff --git a/spec/ruby_llm/chat_streaming_spec.rb b/spec/ruby_llm/chat_streaming_spec.rb index a42bf9ca4..ce6ae8f5f 100644 --- a/spec/ruby_llm/chat_streaming_spec.rb +++ b/spec/ruby_llm/chat_streaming_spec.rb @@ -8,13 +8,15 @@ describe 'streaming responses' do [ - 'claude-3-5-haiku-20241022', - 'gemini-2.0-flash', - 'deepseek-chat', - 'gpt-4o-mini' - ].each do |model| - it "#{model} supports streaming responses" do # rubocop:disable RSpec/ExampleLength,RSpec/MultipleExpectations - chat = RubyLLM.chat(model: model) + ['claude-3-5-haiku-20241022', nil], + ['gemini-2.0-flash', nil], + ['deepseek-chat', nil], + ['gpt-4o-mini', nil], + %w[claude-3-5-haiku bedrock] + ].each do |model, provider| + provider_suffix = provider ? " with #{provider}" : '' + it "#{model} supports streaming responses#{provider_suffix}" do # rubocop:disable RSpec/ExampleLength,RSpec/MultipleExpectations + chat = RubyLLM.chat(model: model, provider: provider) chunks = [] chat.ask('Count from 1 to 3') do |chunk| diff --git a/spec/ruby_llm/chat_tools_spec.rb b/spec/ruby_llm/chat_tools_spec.rb index daa0821a5..855c610ab 100644 --- a/spec/ruby_llm/chat_tools_spec.rb +++ b/spec/ruby_llm/chat_tools_spec.rb @@ -26,12 +26,14 @@ def execute describe 'function calling' do [ - 'claude-3-5-haiku-20241022', - 'gemini-2.0-flash', - 'gpt-4o-mini' - ].each do |model| - it "#{model} can use tools" do # rubocop:disable RSpec/MultipleExpectations - chat = RubyLLM.chat(model: model) + ['claude-3-5-haiku-20241022', nil], + ['gemini-2.0-flash', nil], + ['gpt-4o-mini', nil], + %w[claude-3-5-haiku bedrock] + ].each do |model, provider| + provider_suffix = provider ? " with #{provider}" : '' + it "#{model} can use tools#{provider_suffix}" do # rubocop:disable RSpec/MultipleExpectations + chat = RubyLLM.chat(model: model, provider: provider) .with_tool(Weather) response = chat.ask("What's the weather in Berlin? (52.5200, 13.4050)") @@ -39,8 +41,8 @@ def execute expect(response.content).to include('10') end - it "#{model} can use tools in multi-turn conversations" do # rubocop:disable RSpec/ExampleLength,RSpec/MultipleExpectations - chat = RubyLLM.chat(model: model) + it "#{model} can use tools in multi-turn conversations#{provider_suffix}" do # rubocop:disable RSpec/ExampleLength,RSpec/MultipleExpectations + chat = RubyLLM.chat(model: model, provider: provider) .with_tool(Weather) response = chat.ask("What's the weather in Berlin? (52.5200, 13.4050)") @@ -52,14 +54,14 @@ def execute expect(response.content).to include('10') end - it "#{model} can use tools without parameters" do - chat = RubyLLM.chat(model: model).with_tool(BestLanguageToLearn) + it "#{model} can use tools without parameters#{provider_suffix}" do + chat = RubyLLM.chat(model: model, provider: provider).with_tool(BestLanguageToLearn) response = chat.ask("What's the best language to learn?") expect(response.content).to include('Ruby') end - it "#{model} can use tools with multi-turn streaming conversations" do # rubocop:disable RSpec/ExampleLength,RSpec/MultipleExpectations - chat = RubyLLM.chat(model: model) + it "#{model} can use tools with multi-turn streaming conversations#{provider_suffix}" do # rubocop:disable RSpec/ExampleLength,RSpec/MultipleExpectations + chat = RubyLLM.chat(model: model, provider: provider) .with_tool(Weather) chunks = [] diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 26aea5dfd..a4fdfedeb 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -45,6 +45,8 @@ config.filter_sensitive_data('') { ENV.fetch('ANTHROPIC_API_KEY', nil) } config.filter_sensitive_data('') { ENV.fetch('GEMINI_API_KEY', nil) } config.filter_sensitive_data('') { ENV.fetch('DEEPSEEK_API_KEY', nil) } + config.filter_sensitive_data('') { ENV.fetch('AWS_ACCESS_KEY_ID', nil) } + config.filter_sensitive_data('') { ENV.fetch('AWS_SESSION_TOKEN', nil) } # Filter sensitive response headers config.filter_sensitive_data('') do |interaction| @@ -88,6 +90,10 @@ config.anthropic_api_key = ENV.fetch('ANTHROPIC_API_KEY', 'test') config.gemini_api_key = ENV.fetch('GEMINI_API_KEY', 'test') config.deepseek_api_key = ENV.fetch('DEEPSEEK_API_KEY', 'test') + config.bedrock_api_key = ENV.fetch('AWS_ACCESS_KEY_ID', 'test') + config.bedrock_secret_key = ENV.fetch('AWS_SECRET_ACCESS_KEY', 'test') + config.bedrock_region = ENV.fetch('AWS_REGION', 'us-west-2') + config.bedrock_session_token = ENV.fetch('AWS_SESSION_TOKEN', 'test') config.max_retries = 50 end end