Reputation: 990
Invoke Bedrock Agent using the Javacript SDK v3. Link to the SDK: InvokeAgentCommand
Here's my code so far:
const { BedrockAgentRuntimeClient, InvokeAgentCommand } = require("@aws-sdk/client-bedrock-agent-runtime");
const config = {
accessKeyId: process.env.AWS_BEDROCK_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_BEDROCK_SECRET_ACCESS_KEY,
};
const client = new BedrockAgentRuntimeClient(config);
const input = {
agentId: "agentId",
agentAliasId: "agentAliasId",
sessionId: "abc123",
inputText: "Hello",
};
async invokeAgent() {
return new Promise(async (resolve, reject) => {
const command = new InvokeAgentCommand(input);
const response = await client.send(command);
resolve(response);
});
}
The response I get currently from the endpoint is:
{
"$metadata": {
"httpStatusCode": 200,
"requestId": "reqId",
"attempts": 1,
"totalRetryDelay": 0
},
"contentType": "application/json",
"sessionId": "abc123",
"completion": {
"options": {
"messageStream": {
"options": {
"inputStream": {},
"decoder": {
"headerMarshaller": {},
"messageBuffer": [],
"isEndOfStream": false
}
}
}
}
}
}
There is no error that is specified in the SDK either.
Upvotes: 1
Views: 2954
Reputation: 41
For getting trace events, you also need to loop over chunkEvent.trace
.
const {
BedrockAgentRuntimeClient,
InvokeAgentCommand
} = require("@aws-sdk/client-bedrock-agent-runtime");
const credentials = {
accessKeyId: "accessKeyId",
secretAccessKey: "secretAccessKey",
sessionToken: "sessionToken"
};
const invokingAgent = async(newPayload) => {
const client = new BedrockAgentRuntimeClient({
region: "us-west-2",
credentials: credentials
});
console.log("client endpoint: ", client.config.endpoint);
const command = new InvokeAgentCommand({ ...newPayload
});
let runningResponseText = '';
let runningTraces = [];
let requestId = '';
let intermediatePayload = null;
try {
let completion = "";
const response = await client.send(command);
if (response.completion === undefined) {
throw new Error("Completion is undefined");
}
if (response.completion) {
requestId = response.$metadata.requestId;
console.log("requestId: ", response.$metadata);
for await (const event of response.completion) {
if (event.chunk) {
const response = new TextDecoder('utf-8').decode(event.chunk.bytes);
runningResponseText += response;
}
if (event.trace) {
runningTraces = [...runningTraces, event.trace];
}
if (event.returnControl ? .invocationInputs) {
intermediatePayload = {
requestId,
traces: runningTraces,
invocationInputs: event.returnControl.invocationInputs,
invocationId: event.returnControl.invocationId,
};
}
}
console.log("chunk response: ", runningResponseText);
console.log("returnControl: ", intermediatePayload);
console.log("trace: ", runningTraces);
return runningResponseText;
}
} catch (e) {
console.log("Error occurred L50");
console.error(e);
}
};
const inputPayload = {
agentId: "AGENTID",
agentAliasId: "ALIASID",
sessionId: "sessionId123new",
inputText: "can you help with historical weather ? ",
enableTrace: true
};
(async() => {
try {
const result = await invokingAgent(inputPayload);
console.log(result);
} catch (error) {
console.error("Error:", error);
}
})();
Upvotes: 4
Reputation: 990
In the example(invoke a bedrock agent using the API) that was given there was no high level documentation informing users about the need to properly handle the asynchronous nature of streaming data in this case.
async invokeAgent() {
return new Promise(async (resolve, reject) => {
let completion = "";
const command = new InvokeAgentCommand(input);
const response = await client.send(command);
for await (const chunkEvent of response.completion) {
if (chunkEvent.chunk) {
const chunk = chunkEvent.chunk;
let decoded = new TextDecoder("utf-8").decode(chunk.bytes);
completion += decoded;
}
}
resolve(response);
});
}
for await
is used to iterate over the chunks
in the response asynchronously. The loop will wait for each chunk to be available before moving on to the next iteration.
Upvotes: 4