Description
Environment information
System:
OS: Windows 11 10.0.26100
CPU: (16) x64 13th Gen Intel(R) Core(TM) i7-1360P
Memory: 7.03 GB / 31.68 GB
Binaries:
Node: 20.16.0 - ~\AppData\Local\fnm_multishells\6260_1749764741213\node.EXE
Yarn: 4.9.1 - ~\AppData\Local\fnm_multishells\6260_1749764741213\yarn.CMD
npm: 10.8.1 - ~\AppData\Local\fnm_multishells\6260_1749764741213\npm.CMD
pnpm: undefined - undefined
NPM Packages:
@aws-amplify/ai-constructs: 1.3.0
@aws-amplify/auth-construct: 1.8.1
@aws-amplify/backend: 1.16.1
@aws-amplify/backend-ai: 1.5.1
@aws-amplify/backend-auth: 1.7.1
@aws-amplify/backend-cli: 1.7.2
@aws-amplify/backend-data: 1.6.1
@aws-amplify/backend-deployer: 2.1.1
@aws-amplify/backend-function: 1.14.1
@aws-amplify/backend-output-schemas: 1.6.0
@aws-amplify/backend-output-storage: 1.3.1
@aws-amplify/backend-secret: 1.4.0
@aws-amplify/backend-storage: 1.4.1
@aws-amplify/cli-core: 2.1.1
@aws-amplify/client-config: 1.7.0
@aws-amplify/data-construct: 1.16.1
@aws-amplify/data-schema: 1.20.4
@aws-amplify/deployed-backend-client: 1.7.0
@aws-amplify/form-generator: 1.2.1
@aws-amplify/model-generator: 1.2.0
@aws-amplify/platform-core: 1.9.0
@aws-amplify/plugin-types: 1.10.1
@aws-amplify/sandbox: 2.1.2
@aws-amplify/schema-generator: 1.4.0
@aws-cdk/toolkit-lib: 0.3.2
aws-amplify: 6.15.0
aws-cdk-lib: 2.190.0
typescript: 5.8.3
AWS environment variables:
AWS_PROFILE = gsf-amplify
No CDK environment variables
Data packages
[email protected] C:\Users\TimWeisbrod\SourceCode\gsf\cash-ops
├─┬ @aws-amplify/[email protected]
│ └─┬ @aws-amplify/[email protected]
│ └── @aws-amplify/[email protected]
└─┬ @aws-amplify/[email protected]
└─┬ @aws-amplify/[email protected]
└── @aws-amplify/[email protected]
Description
We have a Gen2 app using postgres as the back end, which uses Cognito user pools for authentication.
We just went through the AI Kit Setup (https://docs.amplify.aws/react/ai/set-up-ai/) to add it, and followed the example closely with the exception of having top add in a.combine to generate a schema with both our Postgres SQL models and also the new chat routes which store data in Dynamo DB. To combine the schemas we followed the code examples in the docs where they show how to connect to external databases like Postgres and how you can combine them with other DynamoDB tables.
const combinedSchema = a.combine([schema, sqlSchema]);
export type Schema = ClientSchema<typeof combinedSchema>;
export const data = defineData({
schema: combinedSchema,
authorizationModes: {
defaultAuthorizationMode: "userPool",
},
});
We got the AIConversation component running on a new page in our app, and when we enter a question into the component we load the page we can see it create a record in the ConversationChat table in DynamoDB, but then it fails to get a subscription with this error in the console which seems to be in "await in _startSubscriptionWithAWSAppSyncRealTime":
{
"errors": [
{
"message": "Connection failed: "
}
]
}
From looking at the network tab, the graphql websocket connection first sends this data payload:
{"type":"connection_init"}
To which it receives this response:
{"payload":{"errors":[{"message":"Required headers are missing.","errorCode":400}]},"type":"connection_error"}
When looking at headers for that vs other graphQL calls I can see that the Authorization header is missing in the subscription, which I am guessing is causing this issue.
Other than that the AI integration appears to be working, because I can submit a question, which I see recorded in the ConversationMessageChat table in DynamoDB & then I see the response back from Bedrock recorded in Dynamo too, but it never surfaces in the front end because the graphql subscription fails.
I also followed the steps in this link to setup cross-region inference so we could use one of the newer Claude models: aws-amplify/docs#8121
In addition to just using the AIConversation component, we also followed the directions here to have more control over the front end experience, but that experiences the same connection failure issue:
https://docs.amplify.aws/react/ai/conversation/connect-your-frontend/
Here are more details on some of our relevant code from resource.ts for reference:
import { schema as generatedSqlSchema } from "./schema.sql";
const sqlSchema = generatedSqlSchema
.authorization((allow) => [
allow.authenticated(),
allow.resource(preTokenGeneration),
allow.resource(postConfirmation),
allow.resource(enrichFinancialTransactions),
allow.resource(getExchangeToken),
allow.resource(getLinkToken),
allow.resource(getAccountInfo),
allow.resource(handlePlaidWebhook),
allow.resource(processIntegrationQue),
allow.resource(handlePayPalAccessToken),
allow.resource(handleQuickBooksAccessToken),
allow.resource(handleDailyIntegrationEvent),
allow.resource(handleBillExpenseConnect),
])
....
export const model = "anthropic.claude-sonnet-4-20250514-v1:0";
export const crossRegionModel = us.${model}
;
export const conversationHandler = defineConversationHandlerFunction({
entry: "./conversationHandler.ts",
name: "conversationHandler",
models: [{ modelId: crossRegionModel }],
});
const schema = a.schema({
// Add a new conversation route to Amplify Data backend.
chat: a
.conversation({
aiModel: {
resourcePath: crossRegionModel,
},
systemPrompt:
"You are a seasoned cash flow expert named Penny with deep experience in financial forecasting, working capital management, and liquidity planning. Your role is to support business leaders, CFOs, and finance teams by providing clear, practical, and strategic guidance to improve cash flow visibility, optimize capital efficiency, and make informed decisions. You think like a trusted advisor—translating complex data into actionable insights, anticipating financial risks, and proposing solutions aligned with business goals.",
handler: conversationHandler,
})
.authorization((allow) => allow.owner()),
chatNamer: a
.generation({
aiModel: a.ai.model("Claude 3 Haiku"),
systemPrompt: You are a helpful assistant that writes descriptive names for conversations. Names should be 2-10 words long
,
})
.arguments({
content: a.string(),
})
.returns(
a.customType({
name: a.string(),
})
)
.authorization((allow) => [allow.authenticated()]),
});
const combinedSchema = a.combine([schema, sqlSchema]);
export type Schema = ClientSchema;
export const data = defineData({
schema: combinedSchema,
authorizationModes: {
defaultAuthorizationMode: "userPool",
},
});