AWS Security ChangesHomeSearch

AWS code-library documentation change

Service: code-library · 2025-04-14 · Documentation low

File: code-library/latest/ug/javascript_3_bedrock-runtime_code_examples.md

Summary

Added detailed code examples demonstrating tool integration with Amazon Bedrock's Converse API, including weather API and music tool scenarios. Includes system prompts restricting tool usage and error handling.

Security assessment

The changes demonstrate secure tool configuration practices (restricting model to specific tools, preventing external data access) but do not address a specific security vulnerability. System prompts enforce security controls as a feature.

Diff

diff --git a/code-library/latest/ug/javascript_3_bedrock-runtime_code_examples.md b/code-library/latest/ug/javascript_3_bedrock-runtime_code_examples.md
index 160ffc54b..b8872f5a2 100644
--- a//code-library/latest/ug/javascript_3_bedrock-runtime_code_examples.md
+++ b//code-library/latest/ug/javascript_3_bedrock-runtime_code_examples.md
@@ -228,0 +229,328 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+The following code example shows how to build a typical interaction between an application, a generative AI model, and connected tools or APIs to mediate interactions between the AI and the outside world. It uses the example of connecting an external weather API to the AI model so it can provide real-time weather information based on user input.
+
+**SDK for JavaScript (v3)**
+    
+
+###### Note
+
+There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javascriptv3/example_code/bedrock-runtime/scenarios/converse_tool_scenario#code-examples). 
+
+The primary execution of the scenario flow. This scenario orchestrates the conversation between the user, the Amazon Bedrock Converse API, and a weather tool.
+    
+    
+    /* Before running this JavaScript code example, set up your development environment, including your credentials.
+    This demo illustrates a tool use scenario using Amazon Bedrock's Converse API and a weather tool.
+    The script interacts with a foundation model on Amazon Bedrock to provide weather information based on user
+    input. It uses the Open-Meteo API (https://open-meteo.com) to retrieve current weather data for a given location.*/
+    
+    import {
+      Scenario,
+      ScenarioAction,
+      ScenarioInput,
+      ScenarioOutput,
+    } from "@aws-doc-sdk-examples/lib/scenario/index.js";
+    import {
+      BedrockRuntimeClient,
+      ConverseCommand,
+    } from "@aws-sdk/client-bedrock-runtime";
+    
+    import { parseArgs } from "node:util";
+    import { fileURLToPath } from "node:url";
+    import { dirname } from "node:path";
+    const __filename = fileURLToPath(import.meta.url);
+    import data from "./questions.json" with { type: "json" };
+    import toolConfig from "./tool_config.json" with { type: "json" };
+    
+    const systemPrompt = [
+      {
+        text:
+          "You are a weather assistant that provides current weather data for user-specified locations using only\n" +
+          "the Weather_Tool, which expects latitude and longitude. Infer the coordinates from the location yourself.\n" +
+          "If the user provides coordinates, infer the approximate location and refer to it in your response.\n" +
+          "To use the tool, you strictly apply the provided tool specification.\n" +
+          "If the user specifies a state, country, or region, infer the locations of cities within that state.\n" +
+          "\n" +
+          "- Explain your step-by-step process, and give brief updates before each step.\n" +
+          "- Only use the Weather_Tool for data. Never guess or make up information. \n" +
+          "- Repeat the tool use for subsequent requests if necessary.\n" +
+          "- If the tool errors, apologize, explain weather is unavailable, and suggest other options.\n" +
+          "- Report temperatures in °C (°F) and wind in km/h (mph). Keep weather reports concise. Sparingly use\n" +
+          "  emojis where appropriate.\n" +
+          "- Only respond to weather queries. Remind off-topic users of your purpose. \n" +
+          "- Never claim to search online, access external data, or use tools besides Weather_Tool.\n" +
+          "- Complete the entire process until you have all required data before sending the complete response.",
+      },
+    ];
+    const tools_config = toolConfig;
+    
+    /// Starts the conversation with the user and handles the interaction with Bedrock.
+    async function askQuestion(userMessage) {
+      // The maximum number of recursive calls allowed in the tool use function.
+      // This helps prevent infinite loops and potential performance issues.
+      const max_recursions = 5;
+      const messages = [
+        {
+          role: "user",
+          content: [{ text: userMessage }],
+        },
+      ];
+      try {
+        const response = await SendConversationtoBedrock(messages);
+        await ProcessModelResponseAsync(response, messages, max_recursions);
+      } catch (error) {
+        console.log("error ", error);
+      }
+    }
+    
+    // Sends the conversation, the system prompt, and the tool spec to Amazon Bedrock, and returns the response.
+    // param "messages" - The conversation history including the next message to send.
+    // return - The response from Amazon Bedrock.
+    async function SendConversationtoBedrock(messages) {
+      const bedRockRuntimeClient = new BedrockRuntimeClient({
+        region: "us-east-1",
+      });
+      try {
+        const modelId = "amazon.nova-lite-v1:0";
+        const response = await bedRockRuntimeClient.send(
+          new ConverseCommand({
+            modelId: modelId,
+            messages: messages,
+            system: systemPrompt,
+            toolConfig: tools_config,
+          }),
+        );
+        return response;
+      } catch (caught) {
+        if (caught.name === "ModelNotReady") {
+          console.log(
+            "`${caught.name}` - Model not ready, please wait and try again.",
+          );
+          throw caught;
+        }
+        if (caught.name === "BedrockRuntimeException") {
+          console.log(
+            '`${caught.name}` - "Error occurred while sending Converse request.',
+          );
+          throw caught;
+        }
+      }
+    }
+    
+    // Processes the response received via Amazon Bedrock and performs the necessary actions based on the stop reason.
+    // param "response" - The model's response returned via Amazon Bedrock.
+    // param "messages" - The conversation history.
+    // param "max_recursions" - The maximum number of recursive calls allowed.
+    async function ProcessModelResponseAsync(response, messages, max_recursions) {
+      if (max_recursions <= 0) {
+        await HandleToolUseAsync(response, messages);
+      }
+      if (response.stopReason === "tool_use") {
+        await HandleToolUseAsync(response, messages, max_recursions - 1);
+      }
+      if (response.stopReason === "end_turn") {
+        const messageToPrint = response.output.message.content[0].text;
+        console.log(messageToPrint.replace(/<[^>]+>/g, ""));
+      }
+    }
+    // Handles the tool use case by invoking the specified tool and sending the tool's response back to Bedrock.
+    // The tool response is appended to the conversation, and the conversation is sent back to Amazon Bedrock for further processing.
+    // param "response" - the model's response containing the tool use request.
+    // param "messages" - the conversation history.
+    // param "max_recursions" - The maximum number of recursive calls allowed.
+    async function HandleToolUseAsync(response, messages, max_recursions) {
+      const toolResultFinal = [];
+      try {
+        const output_message = response.output.message;
+        messages.push(output_message);
+        const toolRequests = output_message.content;
+        const toolMessage = toolRequests[0].text;
+        console.log(toolMessage.replace(/<[^>]+>/g, ""));
+        for (const toolRequest of toolRequests) {
+          if (Object.hasOwn(toolRequest, "toolUse")) {
+            const toolUse = toolRequest.toolUse;
+            const latitude = toolUse.input.latitude;
+            const longitude = toolUse.input.longitude;
+            const toolUseID = toolUse.toolUseId;
+            console.log(
+              `Requesting tool ${toolUse.name}, Tool use id ${toolUseID}`,
+            );
+            if (toolUse.name === "Weather_Tool") {
+              try {
+                const current_weather = await callWeatherTool(
+                  longitude,
+                  latitude,
+                ).then((current_weather) => current_weather);
+                const currentWeather = current_weather;
+                const toolResult = {
+                  toolResult: {
+                    toolUseId: toolUseID,
+                    content: [{ json: currentWeather }],
+                  },
+                };
+                toolResultFinal.push(toolResult);
+              } catch (err) {
+                console.log("An error occurred. ", err);
+              }
+            }
+          }
+        }
+    
+        const toolResultMessage = {
+          role: "user",
+          content: toolResultFinal,
+        };
+        messages.push(toolResultMessage);
+        // Send the conversation to Amazon Bedrock
+        await ProcessModelResponseAsync(
+          await SendConversationtoBedrock(messages),
+          messages,
+        );
+      } catch (error) {
+        console.log("An error occurred. ", error);
+      }
+    }
+    // Call the Weathertool.
+    // param = longitude of location
+    // param = latitude of location
+    async function callWeatherTool(longitude, latitude) {
+      // Open-Meteo API endpoint
+      const apiUrl = `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&current_weather=true`;
+    
+      // Fetch the weather data.
+      return fetch(apiUrl)
+        .then((response) => {
+          return response.json().then((current_weather) => {
+            return current_weather;