-
Notifications
You must be signed in to change notification settings - Fork 634
Description
Checkboxes for prior research
- I've gone through Developer Guide and API reference
- I've checked AWS Forums and StackOverflow.
- I've searched for previous similar issues and didn't find any solution.
Describe the bug
Bedrock agent runtime invokeAgent() returns an unusable response, specifically when using react native expo (I'm not sure about vanilla react native).
Here is a response given by invokeAgent when called by the js sdk in expo
{
"$metadata": {
"httpStatusCode": 200,
"requestId": "[REDACTED]",
"attempts": 1,
"totalRetryDelay": 0
},
"contentType": "application/json",
"sessionId": "[REDACTED]",
"completion": {
"options": {
"messageStream": {
"options": {
"inputStream": {},
"decoder": {
"headerMarshaller": {},
"messageBuffer": [],
"isEndOfStream": false
}
}
}
}
}
}
As far as I can tell, this is a correct response. However, when trying to parse this using the below method I get this error: [TypeError: source[Symbol.asyncIterator] is not a function (it is undefined)]
let completion = '';
if (!invokeAgentOutput.completion) {
throw new Error('Completion is undefined');
}
for await (const chunkEvent of invokeAgentOutput.completion) {
const chunk = chunkEvent.chunk;
// console.log(chunk);
const decodedResponse = new TextDecoder('utf-8').decode(chunk?.bytes);
completion += decodedResponse;
}
Weirdly enough, this issue does not occur on React web application. I recreated the application in React web, with the same auth methods and the same use of the libraries, and the same code correctly returns the agent's response
Regression Issue
- Select this option if this issue appears to be a regression.
SDK version number
"@aws-sdk/client-bedrock-agent-runtime": "^3.826.0"
Which JavaScript Runtime is this issue in?
React Native
Details of the browser/Node.js/ReactNative version
"expo": "~53.0.11", "react-native": "0.79.3",
Reproduction Steps
Create a fresh react native expo project using: npx create-expo-app@latest
Install necessary dependencies for auth and bedrock agent client. I'm using Cognito
Instantiate the Bedrock Agent Runtime Client, and give it credentials
const client: BedrockAgentRuntimeClient = new BedrockAgentRuntimeClient({region: 'us-east-2'});
client.config.credentials = fromCognitoIdentityPool({
clientConfig: {region: 'us-east-2'},
identityPoolId,
logins: {
[session.getIdToken().payload['iss'].split('https://')[1]]: idToken
}
}); // Credentials from cognito
Create a session using the client, and invoke the agent using the client
const createSessionCommand: CreateSessionCommand = new CreateSessionCommand({});
const createSessionOutput: CreateSessionCommandOutput =
await bedrockClient.client.send(createSessionCommand);
const invokeAgentInput: InvokeAgentCommandInput = {
agentId: {{Agent id}},
agentAliasId: {{Alias id}},
inputText: 'This is a test prompt',
sessionId: createSessionOutput.sessionId
};
const invokeAgentCommand: InvokeAgentCommand = new InvokeAgentCommand(invokeAgentInput);
const invokeAgentOutput: InvokeAgentCommandOutput =
await bedrockClient.client.send(invokeAgentCommand);
console.log(`InvokeAgentCommandOutput: ${JSON.stringify(invokeAgentOutput, null, 2)}`);
I'm parsing the response using the only method I've found online
let completion = "";
if (!invokeAgentOutput.completion) {
throw new Error("Completion is undefined");
}
for await (const chunkEvent of invokeAgentOutput.completion) {
const chunk = chunkEvent.chunk;
console.log(chunk);
const decodedResponse = new TextDecoder("utf-8").decode(chunk?.bytes);
completion += decodedResponse;
}
console.log(`Completion: ${completion}`);
Trying to build that will fail, because of an issue I found that can be fixed by babel. To fix:
npm install @babel/plugin-transform-class-static-block
Create a babel.config.json file in the root project directory with content of
{
"plugins": ["@babel/plugin-transform-class-static-block"]
}
You will also need to npm install 'react-native-get-random-values' and import in it the topmost component. This is due to issue with uuid used in the sdk and react native.
Finally you can run the code, and see that this error ([TypeError: source[Symbol.asyncIterator] is not a function) is thrown during parsing. Even though the client is correctly authed, and just called a bedrock function in createSession that worked perfectly fine.
As I mentioned earlier, I recreated this in web React. The same code can parse the correctly formatted response that is returned on the web, and I get the model's response. That is why, to the best of my ability, I think this is an issue with the js-sdk mixing with React Native.
Here's the response I get from the React web page
{
"$metadata": {
"httpStatusCode": 200,
"requestId": "[REDACTED]",
"attempts": 1,
"totalRetryDelay": 0
},
"contentType": "application/json",
"sessionId": "[REDACTED]",
"completion": {
"options": {
"messageStream": {
"options": {
"inputStream": {},
"decoder": {
"headerMarshaller": {},
"messageBuffer": [],
"isEndOfStream": false
}
}
}
}
}
}
Observed Behavior
Error is thrown while trying to parse chunk information
[TypeError: source[Symbol.asyncIterator] is not a function
Expected Behavior
Chunk information should be parsed correctly
Possible Solution
No response
Additional Information/Context
I tested all of this code in an android emulator, as I have no ability to test on iOS (I'm using windows).
I tested as far back as this sdk version (2 months ago)
"@aws-sdk/client-bedrock-agent-runtime": "3.787.0",
Finally, I'll draw attention to the only other place on the internet I could find someone experiencing this issue
#6519
Of course, the issue was never resolved, but a fix was provided by @zshzbh . I tried to implement this fix to no avail.
The fix is:
npm install react-native-get-random-values (I did this earlier)
npm install react-native-url-polyfill
npm install web-streams-polyfill
Include these import statements in the topmost component:
import "react-native-get-random-values";
import "react-native-url-polyfill/auto";
import "web-streams-polyfill/dist/polyfill";
Create a metro config using: npx expo customize metro.config.js
And then add this line: config.resolver.unstable_enablePackageExports = true;
Now clear the metro cache, and rebuild
Unfortunately, this doesn't do anything, and the same issue occurs