Skip to content

Commit b1de8d2

Browse files
committed
rolled in review comments
1 parent 4a51252 commit b1de8d2

File tree

4 files changed

+106
-100
lines changed

4 files changed

+106
-100
lines changed

.doc_gen/metadata/bedrock-runtime_metadata.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,6 +1484,22 @@ bedrock-runtime_Scenario_ToolUseDemo_AmazonNova:
14841484
synopsis: "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."
14851485
category: Amazon Nova
14861486
languages:
1487+
Java:
1488+
versions:
1489+
- sdk_version: 2
1490+
github: javav2/example_code/bedrock-runtime
1491+
excerpts:
1492+
- description: "The primary execution of the scenario flow. This scenario orchestrates the conversation between the user, the &BR; Converse API, and a weather tool."
1493+
snippet_tags:
1494+
- bedrock.converseTool.javav2.scenario
1495+
- description: "The weather tool used by the demo. This file defines the tool specification and implements the logic to retrieve weather data using from the Open-Meteo API."
1496+
genai: some
1497+
snippet_tags:
1498+
- bedrock.converseTool.javav2.weathertool
1499+
- description: "The Converse API action with a tool configuration."
1500+
genai: some
1501+
snippet_tags:
1502+
- bedrockruntime.java2.converse.main
14871503
.NET:
14881504
versions:
14891505
- sdk_version: 3

javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/scenario/BedrockActions.java

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,8 @@
99
import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient;
1010
import software.amazon.awssdk.regions.Region;
1111
import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeAsyncClient;
12-
import software.amazon.awssdk.services.bedrockruntime.model.ConverseRequest;
13-
import software.amazon.awssdk.services.bedrockruntime.model.ConverseResponse;
14-
import software.amazon.awssdk.services.bedrockruntime.model.Message;
15-
import software.amazon.awssdk.services.bedrockruntime.model.SystemContentBlock;
16-
import software.amazon.awssdk.services.bedrockruntime.model.Tool;
17-
import software.amazon.awssdk.services.bedrockruntime.model.ToolConfiguration;
18-
import software.amazon.awssdk.services.bedrockruntime.model.ToolSpecification;
12+
import software.amazon.awssdk.services.bedrockruntime.model.*;
13+
1914
import java.time.Duration;
2015
import java.util.ArrayList;
2116
import java.util.List;
@@ -92,11 +87,11 @@ public ConverseResponse sendConverseRequestAsync(String modelId, String systemPr
9287
ConverseResponse response = getClient().converse(request).join();
9388
return response;
9489

95-
} catch (Exception ex) {
96-
ex.printStackTrace();
90+
} catch (ModelNotReadyException ex) {
91+
throw new RuntimeException("Model is not ready: " + ex.getMessage(), ex);
92+
} catch (BedrockRuntimeException ex) {
93+
throw new RuntimeException("Failed to converse with Bedrock model: " + ex.getMessage(), ex);
9794
}
98-
99-
return null;
10095
}
10196
// snippet-end:[bedrockruntime.java2.converse.main]
10297
}

javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/scenario/BedrockScenario.java

Lines changed: 82 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,9 @@
88
import java.util.Map;
99
import java.util.Objects;
1010
import java.util.Scanner;
11+
1112
import software.amazon.awssdk.core.document.Document;
12-
import software.amazon.awssdk.services.bedrockruntime.model.ContentBlock;
13-
import software.amazon.awssdk.services.bedrockruntime.model.ConversationRole;
14-
import software.amazon.awssdk.services.bedrockruntime.model.ConverseOutput;
15-
import software.amazon.awssdk.services.bedrockruntime.model.ConverseResponse;
16-
import software.amazon.awssdk.services.bedrockruntime.model.Message;
17-
import software.amazon.awssdk.services.bedrockruntime.model.ToolResultBlock;
18-
import software.amazon.awssdk.services.bedrockruntime.model.ToolResultContentBlock;
19-
import software.amazon.awssdk.services.bedrockruntime.model.ToolSpecification;
20-
import software.amazon.awssdk.services.bedrockruntime.model.ToolUseBlock;
13+
import software.amazon.awssdk.services.bedrockruntime.model.*;
2114

2215
// snippet-start:[bedrock.converseTool.javav2.scenario]
2316
/*
@@ -27,7 +20,7 @@
2720
*/
2821
public class BedrockScenario {
2922
public static final String DASHES = new String(new char[80]).replace("\0", "-");
30-
private static String modelId = "anthropic.claude-3-sonnet-20240229-v1:0";
23+
private static String modelId = "amazon.nova-lite-v1:0";
3124
private static String defaultPrompt = "What is the weather like in Seattle?";
3225
private static WeatherTool weatherTool = new WeatherTool();
3326

@@ -38,49 +31,49 @@ public class BedrockScenario {
3831
public static boolean interactive = true;
3932

4033
private static final String systemPrompt = """
41-
You are a weather assistant that provides current weather data for user-specified locations using only
42-
the Weather_Tool, which expects latitude and longitude. Infer the coordinates from the location yourself.
43-
If the user provides coordinates, infer the approximate location and refer to it in your response.
44-
To use the tool, you strictly apply the provided tool specification.
45-
46-
- Explain your step-by-step process, and give brief updates before each step.
47-
- Only use the Weather_Tool for data. Never guess or make up information.
48-
- Repeat the tool use for subsequent requests if necessary.
49-
- If the tool errors, apologize, explain weather is unavailable, and suggest other options.
50-
- Report temperatures in °C (°F) and wind in km/h (mph). Keep weather reports concise. Sparingly use
51-
emojis where appropriate.
52-
- Only respond to weather queries. Remind off-topic users of your purpose.
53-
- Never claim to search online, access external data, or use tools besides Weather_Tool.
54-
- Complete the entire process until you have all required data before sending the complete response.
55-
""";
34+
You are a weather assistant that provides current weather data for user-specified locations using only
35+
the Weather_Tool, which expects latitude and longitude. Infer the coordinates from the location yourself.
36+
If the user provides coordinates, infer the approximate location and refer to it in your response.
37+
To use the tool, you strictly apply the provided tool specification.
38+
39+
- Explain your step-by-step process, and give brief updates before each step.
40+
- Only use the Weather_Tool for data. Never guess or make up information.
41+
- Repeat the tool use for subsequent requests if necessary.
42+
- If the tool errors, apologize, explain weather is unavailable, and suggest other options.
43+
- Report temperatures in °C (°F) and wind in km/h (mph). Keep weather reports concise. Sparingly use
44+
emojis where appropriate.
45+
- Only respond to weather queries. Remind off-topic users of your purpose.
46+
- Never claim to search online, access external data, or use tools besides Weather_Tool.
47+
- Complete the entire process until you have all required data before sending the complete response.
48+
""";
5649

5750
public static void main(String[] args) {
5851
Scanner scanner = new Scanner(System.in);
5952
System.out.println("""
60-
=================================================
61-
Welcome to the Amazon Bedrock Tool Use demo!
62-
=================================================
63-
64-
This assistant provides current weather information for user-specified locations.
65-
You can ask for weather details by providing the location name or coordinates.
66-
67-
Example queries:
68-
- What's the weather like in New York?
69-
- Current weather for latitude 40.70, longitude -74.01
70-
- Is it warmer in Rome or Barcelona today?
71-
72-
To exit the program, simply type 'x' and press Enter.
73-
74-
P.S.: You're not limited to single locations, or even to using English!
75-
Have fun and experiment with the app!
76-
""");
53+
=================================================
54+
Welcome to the Amazon Bedrock Tool Use demo!
55+
=================================================
56+
57+
This assistant provides current weather information for user-specified locations.
58+
You can ask for weather details by providing the location name or coordinates.
59+
60+
Example queries:
61+
- What's the weather like in New York?
62+
- Current weather for latitude 40.70, longitude -74.01
63+
- Is it warmer in Rome or Barcelona today?
64+
65+
To exit the program, simply type 'x' and press Enter.
66+
67+
P.S.: You're not limited to single locations, or even to using English!
68+
Have fun and experiment with the app!
69+
""");
7770
System.out.println(DASHES);
7871

7972
try {
8073
runConversation(scanner);
8174

8275
} catch (Exception ex) {
83-
System.out.println("There was a problem running the scenario: "+ ex.getMessage());
76+
System.out.println("There was a problem running the scenario: " + ex.getMessage());
8477
}
8578

8679
waitForInputToContinue(scanner);
@@ -91,7 +84,7 @@ public static void main(String[] args) {
9184
}
9285

9386
/**
94-
Starts the conversation with the user and handles the interaction with Bedrock.
87+
* Starts the conversation with the user and handles the interaction with Bedrock.
9588
*/
9689
private static List<Message> runConversation(Scanner scanner) {
9790
List<Message> conversation = new ArrayList<>();
@@ -102,16 +95,16 @@ private static List<Message> runConversation(Scanner scanner) {
10295

10396
while (userInput != null) {
10497
ContentBlock block = ContentBlock.builder()
105-
.text(userInput)
106-
.build();
98+
.text(userInput)
99+
.build();
107100

108101
List<ContentBlock> blockList = new ArrayList<>();
109102
blockList.add(block);
110103

111104
Message message = Message.builder()
112-
.role(ConversationRole.USER)
113-
.content(blockList)
114-
.build();
105+
.role(ConversationRole.USER)
106+
.content(blockList)
107+
.build();
115108

116109
conversation.add(message);
117110

@@ -131,9 +124,9 @@ private static List<Message> runConversation(Scanner scanner) {
131124
/**
132125
* Processes the response from the model and updates the conversation accordingly.
133126
*
134-
* @param modelResponse the response from the model
135-
* @param conversation the ongoing conversation
136-
* @param maxRecursion the maximum number of recursions allowed
127+
* @param modelResponse the response from the model
128+
* @param conversation the ongoing conversation
129+
* @param maxRecursion the maximum number of recursions allowed
137130
*/
138131
private static void processModelResponse(ConverseResponse modelResponse, List<Message> conversation, int maxRecursion) {
139132
if (maxRecursion <= 0) {
@@ -150,7 +143,7 @@ private static void processModelResponse(ConverseResponse modelResponse, List<Me
150143
handleToolUse(modelResponse.output(), conversation, maxRecursion - 1);
151144
}
152145

153-
if (modelResponseVal.compareTo ("end_turn") ==0) {
146+
if (modelResponseVal.compareTo("end_turn") == 0) {
154147
// If the stop reason is "end_turn", print the model's response text, and finish the process
155148
PrintModelResponse(modelResponse.output().message().content().get(0).text());
156149
if (!interactive) {
@@ -163,8 +156,8 @@ private static void processModelResponse(ConverseResponse modelResponse, List<Me
163156
* Handles the use of a tool by the model in a conversation.
164157
*
165158
* @param modelResponse the response from the model, which may include a tool use request
166-
* @param conversation the current conversation, which will be updated with the tool use results
167-
* @param maxRecursion the maximum number of recursive calls allowed to handle the model's response
159+
* @param conversation the current conversation, which will be updated with the tool use results
160+
* @param maxRecursion the maximum number of recursive calls allowed to handle the model's response
168161
*/
169162
private static void handleToolUse(ConverseOutput modelResponse, List<Message> conversation, int maxRecursion) {
170163
List<ContentBlock> toolResults = new ArrayList<>();
@@ -182,35 +175,35 @@ private static void handleToolUse(ConverseOutput modelResponse, List<Message> co
182175
// Add the tool use ID and the tool's response to the list of results
183176
List<ToolResultContentBlock> contentBlockList = new ArrayList<>();
184177
ToolResultContentBlock block = ToolResultContentBlock.builder()
185-
.json(toolResponse.getContent())
186-
.build();
178+
.json(toolResponse.getContent())
179+
.build();
187180
contentBlockList.add(block);
188181

189182
ToolResultBlock toolResultBlock = ToolResultBlock.builder()
190-
.toolUseId(toolResponse.getToolUseId())
191-
.content(contentBlockList)
192-
.build();
183+
.toolUseId(toolResponse.getToolUseId())
184+
.content(contentBlockList)
185+
.build();
193186

194187
ContentBlock contentBlock1 = ContentBlock.builder()
195-
.toolResult(toolResultBlock)
196-
.build();
188+
.toolResult(toolResultBlock)
189+
.build();
197190

198191
toolResults.add(contentBlock1);
199192
}
200193
}
201194

202195
// Embed the tool results in a new user message
203196
Message message = Message.builder()
204-
.role(ConversationRole.USER)
205-
.content(toolResults)
206-
.build();
197+
.role(ConversationRole.USER)
198+
.content(toolResults)
199+
.build();
207200

208201
// Append the new message to the ongoing conversation
209202
//conversation.add(message);
210203
conversation.add(message);
211204

212205
// Send the conversation to Amazon Bedrock
213-
var response = sendConversationToBedrock(conversation);
206+
var response = sendConversationToBedrock(conversation);
214207

215208
// Recursively handle the model's response until the model has returned its final response or the recursion counter has reached 0
216209
processModelResponse(response, conversation, maxRecursion);
@@ -221,7 +214,7 @@ private static void handleToolUse(ConverseOutput modelResponse, List<Message> co
221214
private static ToolResponse invokeTool(ToolUseBlock payload) {
222215
String toolName = payload.name();
223216

224-
if (Objects.equals(toolName, "Weather_Tool")){
217+
if (Objects.equals(toolName, "Weather_Tool")) {
225218
Map<String, Document> inputData = payload.input().asMap();
226219
printToolUse(toolName, inputData);
227220

@@ -233,7 +226,7 @@ private static ToolResponse invokeTool(ToolUseBlock payload) {
233226
toolResponse.setToolUseId(payload.toolUseId());
234227
return toolResponse;
235228
} else {
236-
String errorMessage = "The requested tool with name "+toolName +" does not exist.";
229+
String errorMessage = "The requested tool with name " + toolName + " does not exist.";
237230
System.out.println(errorMessage);
238231
return null;
239232
}
@@ -252,8 +245,18 @@ private static void PrintModelResponse(String message) {
252245
private static ConverseResponse sendConversationToBedrock(List<Message> conversation) {
253246
System.out.println("Calling Bedrock...");
254247

255-
// Send the conversation, system prompt, and tool configuration, and return the response
256-
return bedrockActions.sendConverseRequestAsync(modelId, systemPrompt, conversation, weatherTool.getToolSpec());
248+
try {
249+
return bedrockActions.sendConverseRequestAsync(modelId, systemPrompt, conversation, weatherTool.getToolSpec());
250+
} catch (ModelNotReadyException ex) {
251+
System.err.println("Model is not ready. Please try again later: " + ex.getMessage());
252+
throw ex;
253+
} catch (BedrockRuntimeException ex) {
254+
System.err.println("Bedrock service error: " + ex.getMessage());
255+
throw ex;
256+
} catch (RuntimeException ex) {
257+
System.err.println("Unexpected error occurred: " + ex.getMessage());
258+
throw ex;
259+
}
257260
}
258261

259262
private static ConverseResponse sendConversationToBedrockwithSpec(List<Message> conversation, ToolSpecification toolSpec) {
@@ -299,17 +302,16 @@ private static void waitForInputToContinue(Scanner scanner) {
299302
}
300303
}
301304

302-
public static void printFooter()
303-
{
305+
public static void printFooter() {
304306
System.out.println("""
305-
=================================================
306-
Thank you for checking out the Amazon Bedrock Tool Use demo. We hope you
307-
learned something new, or got some inspiration for your own apps today!
308-
309-
For more Bedrock examples in different programming languages, have a look at:
310-
https://docs.aws.amazon.com/bedrock/latest/userguide/service_code_examples.html
311-
=================================================
312-
""");
307+
=================================================
308+
Thank you for checking out the Amazon Bedrock Tool Use demo. We hope you
309+
learned something new, or got some inspiration for your own apps today!
310+
311+
For more Bedrock examples in different programming languages, have a look at:
312+
https://docs.aws.amazon.com/bedrock/latest/userguide/service_code_examples.html
313+
=================================================
314+
""");
313315
}
314316
}
315317
// snippet-end:[bedrock.converseTool.javav2.scenario]

javav2/example_code/bedrock-runtime/src/main/java/com/example/bedrockruntime/scenario/WeatherTool.java

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,12 @@
55

66
import com.fasterxml.jackson.core.type.TypeReference;
77
import com.fasterxml.jackson.databind.ObjectMapper;
8-
import org.json.JSONArray;
98
import software.amazon.awssdk.core.SdkNumber;
109
import software.amazon.awssdk.core.document.Document;
1110
import software.amazon.awssdk.services.bedrockruntime.model.ToolSpecification;
1211
import software.amazon.awssdk.services.bedrockruntime.model.ToolInputSchema;
1312
import org.slf4j.Logger;
1413
import org.slf4j.LoggerFactory;
15-
16-
import java.math.BigInteger;
1714
import java.net.URI;
1815
import java.net.http.HttpClient;
1916
import java.net.http.HttpRequest;
@@ -23,17 +20,13 @@
2320
import java.util.List;
2421
import java.util.Map;
2522
import java.util.concurrent.CompletableFuture;
26-
import java.util.stream.Collectors;
27-
28-
import org.json.JSONObject;
2923

3024
// snippet-start:[bedrock.converseTool.javav2.weathertool]
3125
public class WeatherTool {
3226

3327
private static final Logger logger = LoggerFactory.getLogger(WeatherTool.class);
3428
private static java.net.http.HttpClient httpClient = null;
3529

36-
3730
/**
3831
* Returns the JSON Schema specification for the Weather tool. The tool specification
3932
* defines the input schema and describes the tool's functionality.
@@ -149,9 +142,9 @@ private static Map<String, Document> convertToDocumentMap(Map<String, Object> in
149142
private static Document convertToDocument(Object value) {
150143
if (value instanceof Map) {
151144
return Document.fromMap(convertToDocumentMap((Map<String, Object>) value));
152-
} else if (value instanceof Integer) { // ✅ Fix: Use fromInteger() for integers
145+
} else if (value instanceof Integer) {
153146
return Document.fromNumber(SdkNumber.fromInteger((Integer) value));
154-
} else if (value instanceof Double) { // ✅ Fix: Use fromDouble() for floating-point numbers
147+
} else if (value instanceof Double) { //
155148
return Document.fromNumber(SdkNumber.fromDouble((Double) value));
156149
} else if (value instanceof Boolean) {
157150
return Document.fromBoolean((Boolean) value);

0 commit comments

Comments
 (0)