-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Expand file tree
/
Copy pathconverse-with-tool.js
More file actions
193 lines (180 loc) · 6.41 KB
/
converse-with-tool.js
File metadata and controls
193 lines (180 loc) · 6.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// snippet-start:[Bedrock.ConverseTool.javascriptv3.SendConverseRequest]
// This example demonstrates how to send a conversation of messages to Amazon Nova using Bedrock's Converse API with a tool configuration.
// It shows how to:
// - 1. Set up the Amazon Bedrock runtime client
// - 2. Define the parameters required enable Amazon Bedrock to use a tool when formulating its response (model ID, user input, system prompt, and the tool spec)
// - 3. Send the request to Amazon Bedrock, and returns the response.
// - 4. Add the tool response to the conversation, and send it back to Amazon Bedrock.
// - 5. Publish the response.
import {
BedrockRuntimeClient,
ConverseCommand,
} from "@aws-sdk/client-bedrock-runtime";
// Step 1: Create the Amazon Bedrock runtime client
// Credentials will be automatically loaded from the environment
const bedRockRuntimeClient = new BedrockRuntimeClient({
region: "us-east-1",
});
// Step 2. Define the parameters required enable Amazon Bedrock to use a tool when formulating its response.
// The Bedrock Model ID.
const modelId = "amazon.nova-lite-v1:0";
// The system prompt to help Amazon Bedrock craft it's response.
const system_prompt = [
{
text:
"You are a music expert that provides the most popular song played on a radio station, using only the\n" +
"the top_song tool, which he call sign for the radio station for which you want the most popular song. " +
"Example calls signs are WZPZ and WKRP. \n" +
"- Only use the top_song tool. Never guess or make up information. \n" +
"- If the tool errors, apologize, explain weather is unavailable, and suggest other options.\n" +
"- Only respond to queries about the most popular song played on a radio station\n" +
"Remind off-topic users of your purpose. \n" +
"- Never claim to search online, access external data, or use tools besides the top_song tool.\n",
},
];
// The user's question.
const message = [
{
role: "user",
content: [{ text: "What is the most popular song on WZPZ?" }],
},
];
// The tool specification. In this case, it uses an example schema for
// a tool that gets the most popular song played on a radio station.
const tool_config = {
tools: [
{
toolSpec: {
name: "top_song",
description: "Get the most popular song played on a radio station.",
inputSchema: {
json: {
type: "object",
properties: {
sign: {
type: "string",
description:
"The call sign for the radio station for which you want the most popular song. Example calls signs are WZPZ and WKRP.",
},
},
required: ["sign"],
},
},
},
},
],
};
// Helper function to return the song and artist from top_song tool.
async function get_top_song(call_sign) {
try {
if (call_sign === "WZPZ") {
const song = "Elemental Hotel";
const artist = "8 Storey Hike";
return { song, artist };
}
} catch (error) {
console.log(`${error.message}`);
}
}
// 3. Send the request to Amazon Bedrock, and returns the response.
export async function SendConversationtoBedrock(
modelId,
message,
system_prompt,
tool_config,
) {
try {
const response = await bedRockRuntimeClient.send(
new ConverseCommand({
modelId: modelId,
messages: message,
system: system_prompt,
toolConfig: tool_config,
}),
);
if (response.stopReason === "tool_use") {
const toolResultFinal = [];
try {
const output_message = response.output.message;
message.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 sign = toolUse.input.sign;
const toolUseID = toolUse.toolUseId;
console.log(
`Requesting tool ${toolUse.name}, Tool use id ${toolUseID}`,
);
if (toolUse.name === "top_song") {
const toolResult = [];
try {
const top_song = await get_top_song(toolUse.input.sign).then(
(top_song) => top_song,
);
const toolResult = {
toolResult: {
toolUseId: toolUseID,
content: [
{
json: { song: top_song.song, artist: top_song.artist },
},
],
},
};
toolResultFinal.push(toolResult);
} catch (err) {
const toolResult = {
toolUseId: toolUseID,
content: [{ json: { text: err.message } }],
status: "error",
};
}
}
}
}
const toolResultMessage = {
role: "user",
content: toolResultFinal,
};
// Step 4. Add the tool response to the conversation, and send it back to Amazon Bedrock.
message.push(toolResultMessage);
await SendConversationtoBedrock(
modelId,
message,
system_prompt,
tool_config,
);
} catch (caught) {
console.error(`${caught.message}`);
throw caught;
}
}
// 4. Publish the response.
if (response.stopReason === "end_turn") {
const finalMessage = response.output.message.content[0].text;
const messageToPrint = finalMessage.replace(/<[^>]+>/g);
console.log(messageToPrint.replace(/<[^>]+>/g));
return messageToPrint;
}
} 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;
}
}
}
await SendConversationtoBedrock(modelId, message, system_prompt, tool_config);
// snippet-end:[Bedrock.ConverseTool.javascriptv3.SendConverseRequest]