Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
azaylamba committed Feb 4, 2024
2 parents 8dd11d8 + 1079079 commit 42c6edd
Show file tree
Hide file tree
Showing 38 changed files with 1,310 additions and 6,684 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/stale.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Close stale issues

on:
schedule:
- cron: "38 1 * * *"

permissions:
issues: write
pull-requests: write

jobs:
close-issues:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
days-before-issue-stale: 60
days-before-issue-close: 30
stale-issue-label: "stale"
stale-issue-message: "This issue is stale because it has been open for 60 days with no activity."
close-issue-message: "This issue was closed because it has been inactive for 30 days since being marked as stale."
days-before-pr-stale: -1
days-before-pr-close: -1
repo-token: ${{ secrets.GITHUB_TOKEN }}
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -447,3 +447,9 @@ bin/config.json
docs/.vitepress/cache
docs/.vitepress/dist
lib/user-interface/react-app/.graphqlconfig.yml

# Amplify auto-generated files
lib/user-interface/react-app/src/API.ts
lib/user-interface/react-app/src/graphql/mutations.ts
lib/user-interface/react-app/src/graphql/queries.ts
lib/user-interface/react-app/src/graphql/subscriptions.ts
20 changes: 20 additions & 0 deletions .graphqlconfig.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
projects:
chatbot:
schemaPath: lib/chatbot-api/schema/schema.graphql
includes:
- lib/user-interface/react-app/src/graphql/*.ts
excludes:
- ./amplify/**
extensions:
amplify:
codeGenTarget: typescript
generatedFileName: lib/user-interface/react-app/src/API.ts
docsFilePath: lib/user-interface/react-app/src/graphql/ #The field is not configured correctly and needs to be changed
region: us-east-1
apiId: null
frontend: javascript
framework: react
maxDepth: 2
extensions:
amplify:
version: 3
13 changes: 4 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
[![GitHub star chart](https://img.shields.io/github/stars/aws-samples/aws-genai-llm-chatbot?style=social)](https://star-history.com/#aws-samples/aws-genai-llm-chatbot)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

[![Deploy with GitHub Codespaces](https://github.com/codespaces/badge.svg)](#deploy-with-github-codespaces)
[![Deploy with GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://aws-samples.github.io/aws-genai-llm-chatbot/guide/deploy.html#deploy-with-github-codespaces)

#### [Full documentation](https://aws-samples.github.io/aws-genai-llm-chatbot/)
[![Full Documentation](https://img.shields.io/badge/Full%20Documentation-blue?style=for-the-badge&logo=Vite&logoColor=white)](https://aws-samples.github.io/aws-genai-llm-chatbot/)

![sample](docs/about/assets/chabot-sample.gif "AWS GenAI Chatbot")

Expand All @@ -23,13 +23,8 @@ Supported model providers:
- [Bigad Soleiman](https://www.linkedin.com/in/bigadsoleiman/)
- [Sergey Pugachev](https://www.linkedin.com/in/spugachev/)

# Credits

This sample was made possible thanks to the following libraries:

- [langchain](https://python.langchain.com/docs/get_started/introduction.html) from [LangChain AI](https://github.com/langchain-ai)
- [unstructured](https://github.com/Unstructured-IO/unstructured) from [Unstructured-IO](https://github.com/Unstructured-IO/unstructured)
- [pgvector](https://github.com/pgvector/pgvector) from [Andrew Kane](https://github.com/ankane)
# Contributors
[![contributors](https://contrib.rocks/image?repo=aws-samples/aws-genai-llm-chatbot&max=2000)](https://github.com/aws-samples/aws-genai-llm-chatbot/graphs/contributors)

# License

Expand Down
9 changes: 6 additions & 3 deletions bin/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ export function getConfig(): SystemConfig {
// Default config
return {
prefix: "",
/*vpc: {
vpcId: "vpc-00000000000000000",
createVpcEndpoints: true,
/* vpc: {
vpcId: "vpc-00000000000000000",
createVpcEndpoints: true,
},*/
privateWebsite: false,
certificate : "",
bedrock: {
enabled: true,
region: SupportedRegion.US_EAST_1,
Expand All @@ -33,6 +35,7 @@ export function getConfig(): SystemConfig {
kendra: {
enabled: false,
createIndex: false,
enterprise: false
},
},
embeddingsModels: [
Expand Down
66 changes: 48 additions & 18 deletions cli/magic-create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
SupportedRegion,
SupportedSageMakerModels,
SystemConfig,
SupportedBedrockRegion,
} from "../lib/shared/types";
import { LIB_VERSION } from "./version.js";
import * as fs from "fs";
Expand Down Expand Up @@ -57,6 +58,9 @@ const embeddingModels = [
fs.readFileSync("./bin/config.json").toString("utf8")
);
options.prefix = config.prefix;
options.privateWebsite = config.privateWebsite;
options.certificate = config.certificate;
options.domain = config.domain;
options.bedrockEnable = config.bedrock?.enabled;
options.bedrockRegion = config.bedrock?.region;
options.bedrockRoleArn = config.bedrock?.roleArn;
Expand Down Expand Up @@ -113,6 +117,31 @@ async function processCreateOptions(options: any): Promise<void> {
initial: options.prefix,
askAnswered: false,
},
{
type: "confirm",
name: "privateWebsite",
message:
"Do you want to deploy a private website? I.e only accessible in VPC",
initial: options.privateWebsite || false,
},
{
type: "input",
name: "certificate",
message: "ACM certificate ARN",
initial: options.certificate,
skip(): boolean {
return !(this as any).state.answers.privateWebsite;
},
},
{
type: "input",
name: "domain",
message: "Domain for private website",
initial: options.domain,
skip(): boolean {
return !(this as any).state.answers.privateWebsite;
},
},
{
type: "confirm",
name: "bedrockEnable",
Expand All @@ -123,13 +152,7 @@ async function processCreateOptions(options: any): Promise<void> {
type: "select",
name: "bedrockRegion",
message: "Region where Bedrock is available",
choices: [
SupportedRegion.US_EAST_1,
SupportedRegion.US_WEST_2,
SupportedRegion.EU_CENTRAL_1,
SupportedRegion.AP_SOUTHEAST_1,
SupportedRegion.AP_NORTHEAST_1,
],
choices: Object.values(SupportedBedrockRegion),
initial: options.bedrockRegion ?? "us-east-1",
skip() {
return !(this as any).state.answers.bedrockEnable;
Expand Down Expand Up @@ -208,13 +231,27 @@ async function processCreateOptions(options: any): Promise<void> {
{ message: "OpenSearch", name: "opensearch" },
{ message: "Kendra (managed)", name: "kendra" },
],
validate(choices: any) {
return (this as any).skipped || choices.length > 0
? true
: "You need to select at least one engine";
},
skip(): boolean {
// workaround for https://github.com/enquirer/enquirer/issues/298
(this as any).state._choices = (this as any).state.choices;
return !(this as any).state.answers.enableRag;
},
initial: options.ragsToEnable || [],
},
{
type: "confirm",
name: "kendraEnterprise",
message: "Do you want to enable Kendra Enterprise Edition?",
initial: options.kendraEnterprise || false,
skip(): boolean {
return !(this as any).state.answers.ragsToEnable.includes("kendra");
},
},
{
type: "confirm",
name: "kendra",
Expand All @@ -227,19 +264,9 @@ async function processCreateOptions(options: any): Promise<void> {
return !(this as any).state.answers.enableRag;
},
},
{
type: "confirm",
name: "kendraEnterprise",
message: "Do you want to enable Kendra Enterprise Edition?",
initial: options.kendraEnterprise || false,
skip(): boolean {
return !(this as any).state.answers.ragsToEnable.includes("kendra");
},
},
];
const answers: any = await enquirer.prompt(questions);
console.log(answers);
const kendraExternal = [];
const kendraExternal: any[] = [];
let newKendra = answers.enableRag && answers.kendra;
const existingKendraIndices = Array.from(options.kendraExternal || []);
while (newKendra === true) {
Expand Down Expand Up @@ -328,6 +355,9 @@ async function processCreateOptions(options: any): Promise<void> {
// Create the config object
const config = {
prefix: answers.prefix,
privateWebsite: answers.privateWebsite,
certificate: answers.certificate,
domain: answers.domain,
bedrock: answers.bedrockEnable
? {
enabled: answers.bedrockEnable,
Expand Down
2 changes: 2 additions & 0 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ export default defineConfig({
{
text: 'Documentation',
items: [
{ text: 'Private Chatbot', link: '/documentation/private-chatbot' },
{ text: 'Model Requirements', link: '/documentation/model-requirements' },
{ text: 'Self-hosted models', link: '/documentation/self-hosted-models' },
{ text: 'Inference Script', link: '/documentation/inference-script' },
{ text: 'Document Retrieval', link: '/documentation/retriever' },
{ text: 'AppSync', link: '/documentation/appsync' },
Expand Down
Binary file modified docs/about/assets/architecture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions docs/documentation/private-chatbot.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Private Chatbot

Allows the deployment of a private chatbot via the 'npm run create' CLI setup.

- VPC only accessible website with an Application Load Balancer in front of an S3 hosted website.
- Private Appsync APIs and Web Sockets
- VPC endpoints for AWS services
- Utilises a AWS Private CA certifice
- Utilises a Amazon Route 53 Private Hosted Zone and Domain


### Prerequisites: Private Chatbot Deployment
1. [AWS Private CA issued ACM certificate](https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-private.html) for your chosen domain. (i.e. chatbot.example.org)
2. A Route 53 [Private Hosted Zone](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zones-private.html) (i.e. for example.org)

### During 'npm run create'
```shellsession
$ ✔ Do you want to deploy a private website? I.e only accessible in VPC (Y/n) ·
true
$ ✔ ACM certificate ARN ·
arn:aws:acm:us-east-1:1234567890:certificate/12345678-1234-1234-1234-12345678
$ ✔ Domain for private website ·
chatbot.example.org
```

### After Private Deployment:
1. In Route 53 [link the created VPC to the Private Hosted Zone (PHZ)](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zone-private-associate-vpcs.html)
2. In the PHZ, [add an "A Record"](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-elb-load-balancer.html) with your chosen subdomain (i.e. chatbot.example.org) that points to the website Application Load Balancer Alias.
32 changes: 32 additions & 0 deletions docs/documentation/self-hosted-models.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# SageMaker Model Constructs

This project provides multiple CDK constructs to help facilitate the deployment of models to Amazon SageMaker:
- [SageMaker Jumpstart](https://github.com/awslabs/generative-ai-cdk-constructs/blob/main/src/patterns/gen-ai/aws-model-deployment-sagemaker/README_jumpstart.md): Deploy a foundation model from Amazon SageMaker JumpStart to an Amazon SageMaker endpoint.
- [Hugging Face](https://github.com/awslabs/generative-ai-cdk-constructs/blob/main/src/patterns/gen-ai/aws-model-deployment-sagemaker/README_hugging_face.md): Deploy a foundation model from Hugging Face to an Amazon SageMaker endpoint (models supported by [HuggingFace LLM Inference container](https://huggingface.co/blog/sagemaker-huggingface-llm))
- [Custom model](https://github.com/awslabs/generative-ai-cdk-constructs/blob/main/src/patterns/gen-ai/aws-model-deployment-sagemaker/README_custom_sagemaker_endpoint.md): Deploy a foundation model from an S3 location to an Amazon SageMaker endpoint

These constructs can be consumed separately through the [Generative AI CDK Constructs](https://github.com/awslabs/generative-ai-cdk-constructs) library.

You can see examples in the [lib/models/index.ts](https://github.com/aws-samples/aws-genai-llm-chatbot/blob/main/lib/models/index.ts) file demonstrating how to deploy several models like Llama2 13B chat, Mistral 8x7B or IDEFICS.

For additional samples demonstrating how to deploy models using these constructs, you can refer to the related [samples repository](https://github.com/aws-samples/generative-ai-cdk-constructs-samples).

### Custom inference code

While the options above are preferred, for broader compatibility, the sample also showcases deployment of all other models from Hugging Face not supported by HuggingFace LLM Infernce container using custom inference code. This process is powered by AWS CodeBuild.

For this kind of deployment you need to choose the right container for your model from [this list of AWS Deep Learning Containers](https://github.com/aws/deep-learning-containers/blob/master/available_images.md). Based on PyTorch/Transformers versions, Python version etc. An example on how to use this construct is available [here](https://github.com/aws-samples/aws-genai-llm-chatbot/tree/main/lib/rag-engines/sagemaker-rag-models).

### Adapters

This samples provides [adapters](https://github.com/aws-samples/aws-genai-llm-chatbot/tree/main/lib/model-interfaces/langchain/functions/request-handler/adapters) for several models out of the box. The model you want to deploy might not have an existing adapter available, thus you will need to develop one. [This documentation](https://github.com/aws-samples/aws-genai-llm-chatbot/tree/main/lib/model-interfaces/langchain) provides steps to build you own adapter.

### Precautions

***Cost***: Be mindful of the costs associated with AWS resources, especially with SageMaker models which are billed by the hour. Leaving serverful resources running for extended periods or deploying numerous LLMs can quickly lead to increased costs.

***Licensing***: These constructs allow you to interact with models from third party providers. Your use of the third-party generative AI (GAI) models is governed by the terms provided to you by the third-party GAI model providers when you acquired your license to use them (for example, their terms of service, license agreement, acceptable use policy, and privacy policy).

You are responsible for ensuring that your use of the third-party GAI models comply with the terms governing them, and any laws, rules, regulations, policies, or standards that apply to you.

You are also responsible for making your own independent assessment of the third-party GAI models that you use, including their outputs and how third-party GAI model providers use any data that might be transmitted to them based on your deployment configuration. AWS does not make any representations, warranties, or guarantees regarding the third-party GAI models, which are “Third-Party Content” under your agreement with AWS. This construct is offered to you as “AWS Content” under your agreement with AWS.
1 change: 1 addition & 0 deletions docs/guide/deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ You'll be prompted to configure the different aspects of the solution, such as:

- The LLMs or MLMs to enable (we support all models provided by Bedrock along with SageMaker hosted Idefics, FalconLite, Mistral and more to come)
- Setup of the RAG system: engine selection (i.e. Aurora w/ pgvector, OpenSearch, Kendra..) embeddings selection and more to come.
- Private Chatbot: Limit accessibility to website and backend to VPC.

When done, answer `Y` to create a new configuration.

Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
layout: home

hero:
name: "AWS GenAI LLM Chatbot"
name: "AWS GenAI Chatbot"
text: "Deploying a Multi-Model and Multi-RAG Powered Chatbot Using AWS CDK on AWS"
actions:
- theme: brand
Expand Down
33 changes: 33 additions & 0 deletions lib/aws-genai-llm-chatbot-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -414,5 +414,38 @@ export class AwsGenAILLMChatbotStack extends cdk.Stack {
reason: "Not yet upgraded from Python 3.11 to 3.12.",
},
]);

if (props.config.privateWebsite) {
const paths = [];
for(let index = 0; index < shared.vpc.availabilityZones.length; index++) {
paths.push(`/${this.stackName}/UserInterface/PrivateWebsite/DescribeNetworkInterfaces-${index}/CustomResourcePolicy/Resource`,)
}
paths.push(`/${this.stackName}/UserInterface/PrivateWebsite/describeVpcEndpoints/CustomResourcePolicy/Resource`,)
NagSuppressions.addResourceSuppressionsByPath(
this,
paths,
[
{
id: "AwsSolutions-IAM5",
reason:
"Custom Resource requires permissions to Describe VPC Endpoint Network Interfaces",
},
]
);
NagSuppressions.addResourceSuppressionsByPath(
this,
[
`/${this.stackName}/AWS679f53fac002430cb0da5b7982bd2287/ServiceRole/Resource`
],
[
{
id: "AwsSolutions-IAM4",
reason:
"IAM role implicitly created by CDK.",
},
]
);

}
}
}
2 changes: 2 additions & 0 deletions lib/chatbot-api/appsync-ws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export class RealtimeResolvers extends Construct {
SNS_TOPIC_ARN: props.topic.topicArn,
},
layers: [props.shared.powerToolsLayer],
vpc: props.shared.vpc
});

const outgoingMessageHandler = new NodejsFunction(
Expand All @@ -58,6 +59,7 @@ export class RealtimeResolvers extends Construct {
environment: {
GRAPHQL_ENDPOINT: props.api.graphqlUrl,
},
vpc: props.shared.vpc
}
);

Expand Down
7 changes: 6 additions & 1 deletion lib/chatbot-api/functions/resolvers/subscribe-resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ export function request(ctx) {
}

export function response(ctx) {
const filter = { and: [{ userId: { eq: ctx.identity.sub } }] };
const filter = {
and: [
{ userId: { eq: ctx.identity.sub } },
{ sessionId: { eq: ctx.args.sessionId } },
],
};
extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter));
return null;
}
1 change: 1 addition & 0 deletions lib/chatbot-api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export class ChatBotApi extends Construct {
role: loggingRole,
},
xrayEnabled: true,
visibility: props.config.privateWebsite ? appsync.Visibility.PRIVATE : appsync.Visibility.GLOBAL
});

new ApiResolvers(this, "RestApi", {
Expand Down
Loading

0 comments on commit 42c6edd

Please sign in to comment.