├── App.py ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── README.md ├── cloudformation ├── gen-ai-deploy-template.json └── gen-ai-deploy-template.yaml ├── create-gen-ai-repo-zip.sh ├── docs ├── access.md └── install.md ├── imgs ├── .DS_Store ├── app-stack-output.png ├── bedrock-access-granted.png ├── bedrock-model-accesspage.png ├── bedrock-models.png ├── bedrock.png ├── cloudfront-wafv2-rules.png ├── cloudfront-wafv2.png ├── code-sample-zip.png ├── cognito-user-signup.png ├── cost-reporting1.png ├── cost-reporting2.png ├── create-stack.png ├── docker-config.png ├── enterprise-seach-kendra.png ├── genai-samples-arch.png ├── github-repo-config.png ├── ipset-view.png ├── jumpstart.png ├── llm-models.png ├── request-model-access.png ├── sample-artifact-s3bucket.png ├── sample-artifacts.png ├── sample-usecase.png ├── sample-usecases.png ├── stable-diffusion.png ├── stack-details.png ├── stack-name.png ├── stack-output-cloudfront.png ├── stack-output1.png ├── stack-output2.png ├── stack-outputs-s3buckets.png ├── stack-template.png ├── streamlit-app-login.png ├── streamlit-app-user-signup.png ├── streamlit-app-user-signup1.png ├── streamlit-app-user-signup2.png ├── streamlit-app.png ├── waf-ipruleset1-no.png ├── waf-ipset-allowed-cidr.png ├── waf-stack-output.png ├── waf-stack-template.png ├── waf-stack.png ├── wafv2-ipset-edit.png ├── wafv2-ipsetrule-cidrblocks.png ├── wafv2-ipsets.png └── wafv2.png ├── lambda-srcs ├── lex-fulfillment-function │ ├── lex_fulfillment.py │ ├── requirements.txt │ └── template.yaml ├── lex-rag-lambda-function │ ├── lexbot_rag.py │ ├── requirements.txt │ ├── samconfig.toml.BAK │ └── template.yaml ├── s3-bucket-cleanup-function │ ├── requirements.txt │ ├── s3_bucket_cleanup.py │ └── template.yaml └── sagemaker-deployer-function │ ├── ai21_model_package_arns.json │ ├── deployer.py │ ├── repo_parser.py │ ├── requirements.txt │ └── template.yaml ├── lex-srcs ├── GenAIHotelBookingLexChatbot │ ├── Bot.json │ └── BotLocales │ │ └── en_US │ │ ├── BotLocale.json │ │ ├── Intents │ │ ├── BookHotel │ │ │ ├── ConversationFlow.json │ │ │ ├── Intent.json │ │ │ └── Slots │ │ │ │ ├── CheckInDate │ │ │ │ └── Slot.json │ │ │ │ ├── City │ │ │ │ └── Slot.json │ │ │ │ ├── Comment │ │ │ │ └── Slot.json │ │ │ │ ├── FirstName │ │ │ │ └── Slot.json │ │ │ │ ├── LastName │ │ │ │ └── Slot.json │ │ │ │ ├── NumberOfGuests │ │ │ │ └── Slot.json │ │ │ │ ├── NumberOfNights │ │ │ │ └── Slot.json │ │ │ │ ├── ProvideComment │ │ │ │ └── Slot.json │ │ │ │ └── RoomType │ │ │ │ └── Slot.json │ │ ├── CancelReservation │ │ │ ├── Intent.json │ │ │ └── Slots │ │ │ │ └── ConfirmationNumber │ │ │ │ └── Slot.json │ │ ├── FallbackIntent │ │ │ └── Intent.json │ │ └── Welcome │ │ │ ├── ConversationFlow.json │ │ │ ├── Intent.json │ │ │ └── Slots │ │ │ └── option │ │ │ └── Slot.json │ │ └── SlotTypes │ │ └── RoomTypeValues │ │ └── SlotType.json └── Manifest.json ├── localTestEnvSetup.sh ├── pages ├── GenAI_Agile_Guru.py ├── GenAI_ChatAway.py ├── GenAI_Hotel_Genie.py.txt ├── GenAI_call_analyzer.py ├── GenAI_content_analyzer.py ├── GenAI_enterprise_search_interpreter.py ├── GenAI_product_ideator.py └── imports │ ├── call_bedrock_image.py │ ├── call_bedrock_text.py │ └── sts_assume_role.py ├── pushLatestDockerImage.sh ├── requirements.txt ├── sample-artifacts ├── FicticiousHotelsFAQ.pdf ├── call-analyzer-samples │ ├── sample-call-1.wav │ ├── sample-call-2.wav │ ├── sample-call-3.wav │ ├── sample-call-4.wav │ ├── sample-call-5.wav │ └── sample-call-6.wav ├── code-source-samples │ ├── SubtractNumbers.java │ ├── add_numbers.py │ └── order_entry.cbl ├── content-analyzer-samples │ ├── 2022-amzn-Shareholder-Letter.pdf │ ├── InvoiceBot.json │ ├── Sample-Excel-Household-Organizer.xlsx │ ├── SampleInvoice.xlsx │ ├── SimpleServiceInvoice1.xlsx │ ├── amzn-annualreport-2022.pdf │ ├── buggy_code.py │ ├── sample-presentation.pptx │ └── sample-word.docx ├── general │ └── content │ │ └── empty-file.txt └── personalize │ └── hotel-recommendations │ └── hotel-metadata.csv ├── updateEcsService.sh └── utils ├── cognito_helper.py ├── gen_ai_selector.py └── llm_pricing.csv /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM amazonlinux:2023 2 | 3 | WORKDIR /usr/src/app 4 | 5 | RUN rm -rf /var/lib/apt/lists/* 6 | 7 | RUN dnf check-update && dnf upgrade -y 8 | RUN dnf install git python3 python3-pip python3-setuptools -y 9 | 10 | COPY *.txt ./ 11 | 12 | RUN pip3 install --no-cache-dir -r requirements.txt 13 | 14 | COPY App.py . 15 | COPY pages/ pages/ 16 | COPY utils/ utils/ 17 | 18 | #EXPOSE 8501 19 | EXPOSE 8080 20 | 21 | #HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health || exit 1 22 | HEALTHCHECK CMD curl --fail http://localhost:8080/_stcore/health || exit 1 23 | 24 | RUN groupadd -r streamlit && useradd --no-log-init -r -g streamlit streamlit 25 | RUN chown -R streamlit:streamlit /usr/src/app 26 | USER streamlit 27 | 28 | 29 | ENTRYPOINT [ "streamlit", "run", "App.py", \ 30 | "--logger.level", "info", \ 31 | "--browser.gatherUsageStats", "false", \ 32 | "--browser.serverAddress", "0.0.0.0", \ 33 | "--server.enableCORS", "false", \ 34 | "--server.enableXsrfProtection", "false", \ 35 | "--server.port", "8080"] 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT No Attribution 2 | 3 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 13 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 15 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | ## The AWS Gen AI Demo Showcase 4 | 5 | This GenAI demo showcase consists of multiple demos which demonstrates the art of the possible with Generative AI using AWS services. We have started with 6 popular Gen AI demos demonstrating AWS AI services along with Amazon Bedrock. By deploying this solution, you can explore the power of these services and how they can be integrated to solve various business challenges. 6 | 7 | ## Design 8 | 9 | The code for the demos is built with Python and calls API’s for various services in your AWS account. The front end uses [Streamlit](https://streamlit.io/). The bundled code package is available in this Github repository or as a standalone package. 10 | 11 | Users begin with a AWS CloudFormation template that picks up the related sample application code package from a github repository or from an user managed S3 bucket specified in the input parameters. The stack then builds a Docker image using the code base on a temporary EC2 instance and uploads the docker image to Amazon ECR (Elastic Container Registry). Lambda functions used for Amazon SageMaker Jumpstart deployment and S3 bucket cleanup on deletion of stack are also built on same EC2 instance. The CloudFormation script then creates the additional infrastructure required like ECS Cluster, Fargate Task Definitions to run the docker image as a ECS managed container. Users can update the sources and deploy the package on Amazon ECS Fargate using the Code* tools ( Code Build, Code Commit, Code Pipeline and Code Deploy). 12 | 13 | The template then provisions additional services needed for the demos like IAM Roles, Kendra, Dynamo DB, S3 Buckets for sample data or storing test results, Amazon ALB and CloudFront to make the solution available via the web securely. The Sample Demo application would be accessible via CloudFront with user authentication managed by Cognito. 14 | 15 | In this version of the Demo Showcase, we have selected the most popular demos and we are supporting some of the Amazon Bedrock models only for the demos. In future versions, we will add additional models as well as demos. 16 | 17 | Below is the architecture design of the solution: 18 | 19 | ![](./imgs/genai-samples-arch.png) 20 | 21 | Note: CICD setup is not included in this template. 22 | 23 | 24 | Refer to the following for: 25 | * [Deployment](./docs/install.md) 26 | * [Accessing App](./docs/access.md) 27 | 28 | ### Customizing the samples 29 | If user is interested in modifying the samples or adding more customized usecases, this would require recreation of the Docker image of the streamlit app and uptaking it in ECS. There are two scripts available to recreate the ECS Docker image and push ECS to uptake the changed docker image. Edit the following scripts with correct region, stack id and run with AWS creds from command line. 30 | * `pushLatestDockerImage.sh`: shell script to push updated code as docker image for ECS. Edit the parameters as necessary before running the script. Needs AWS CLI, credentials and Docker along with access to the application code (run from directory where the *Dockerfile* exists). 31 | * `updateEcsService.sh`: shell script to update ECS to uptake any updated docker image or task definitions. Needs AWS CLI and credentials to update ECS. 32 | 33 | There are two helper utiltiies that encapsulate the interactions with Bedrock and Cognito. **utils/gen_ui_selector.py** handles the model selection and invocation of various Bedrock models and **utils/congito_helper.py** handles the user registration/signup, authentication. 34 | 35 | ## License 36 | This sample code and templates are made available under a modified MIT license. 37 | See the LICENSE file for more information. 38 | -------------------------------------------------------------------------------- /create-gen-ai-repo-zip.sh: -------------------------------------------------------------------------------- 1 | GEN_AI_CODE_SAMPLE_ZIP="gen-ai-code.zip" 2 | if [ ! -z "$1" ]; then 3 | GEN_AI_CODE_SAMPLE_ZIP=$1 4 | fi 5 | rm ${GEN_AI_CODE_SAMPLE_ZIP} 6 | zip -r ${GEN_AI_CODE_SAMPLE_ZIP} \ 7 | *.py \ 8 | *.txt \ 9 | Dockerfile \ 10 | pages \ 11 | utils \ 12 | lambda-srcs \ 13 | lex-srcs \ 14 | cloudformation 15 | -------------------------------------------------------------------------------- /docs/access.md: -------------------------------------------------------------------------------- 1 | # Accessing the Streamlit Application 2 | 3 | ### Bedrock Model Access 4 | 5 | Before running the sample application, ensure Bedrock Model access is enabled for the various models (Titan, Anthropic, Meta Llama etc.) by checking the Bedrock Service page in AWS console and requesting access in the specific region where you plan to deploy and test the sample application. 6 | * To request access, visit the Providers page under [Bedrock Services](https://console.aws.amazon.com/bedrock) 7 | ![](../imgs/bedrock-model-accesspage.png) 8 | * Click on the Manage access 9 | ![](../imgs/request-model-access.png) 10 | Once all the models have been granted access, it should look like below 11 | ![](../imgs/bedrock-access-granted.png) 12 | 13 | ### Deployment Results 14 | * Once the deployment is completed, check the Outputs tab of deployed app stack. 15 | ![](../imgs/stack-output1.png) 16 | * Key Outputs: 17 | * CognitoUserPoolID: cognito user pool created to manage user auth 18 | * ECSCluster: ECS Cluster created to run the application. 19 | * ECSService: ECS Service created to run the application. 20 | * GenAISearchInterpreterS3Bucket: S3 bucket that contains search contents that can indexed by Kendra. 21 | 22 | If user is interested in modifying the samples or adding more customized usecases, this would recreation of the docker image of the streamlit app and uptaking it. There are two scripts available to recreate the ECS Docker image and push ECS to uptake the changed docker image. Edit the following scripts with correct region, stack id and run with AWS creds from command line. 23 | * `pushLatestDockerImage.sh`: shell script to push updated code as docker image for ECS. Edit the parameters as necessary before running the script. Needs AWS CLI, credentials and Docker along with access to the application code (run from directory where the *Dockerfile* exists). 24 | * `updateEcsService.sh`: shell script to update ECS to uptake any updated docker image or task definitions. Needs AWS CLI and credentials to update ECS. 25 | 26 | ![](../imgs/stack-output2.png) 27 | * HostedUILoginURL: Cognito Hosted UI Login and User Sign-up page that would then redirect back to the Streamlit app (via CloudFront url) 28 | * LBRSecureTokenHeader: Token required to communicate with the ALB (pass as `X-Custom-Header`), if user wants to test bypassing CloudFront. CloudFront passes this header during its interaction with Loadbalancer. The user auth is separate and managed via Cognito. 29 | 30 | * Check for the **GenAITestS3Bucket** key in the Outputs tab. This will refer to the newly created S3 bucket hosting readymade samples for the demo to utilize. 31 | The Cloudformation script would have already copied over required samples into this bucket for a smooth working demo. 32 | ![](../imgs/sample-artifact-s3bucket.png) 33 | 34 | * The following sample use cases are available in the first version of this solution. 35 | usecases 36 | 37 | * Check for the **KendraIndex** key in the Outputs tab. This refers to the new Kendra Index created. 38 | Go to Kendra service in console, locate the matching Kendra index and then select the Datasource (named GenAIKendraDatasource-*) on left hand panel and sync against with Kendra so it would ingest the Search interpreter demo sample contents. 39 | See Kendra documentation: https://docs.aws.amazon.com/kendra/latest/dg/data-source-s3.html for more details. 40 | 41 | 42 | ### Accessing the Streamlit application 43 | 44 | Once the main stack is deployed with its CloudFront distribution, discover the deployed CloudFront distribution endpoint in the Outputs tab and access it in a new window. 45 | * `PublicSecureCFDistribution` is the link to the CloudFront distribution endpoint. 46 | ![](../imgs/stack-output-cloudfront.png) 47 | 48 | This will launch the Gen AI Demo showcase as shown below with a Login form. This front end uses Streamlit. Login requires a valid user. 49 | ![](../imgs/streamlit-app-login.png) 50 | * Use the signup button to create and register as a new user using the rendred UI. Also, one can use the Cognito Hosted UI to sign up but it does not support custom user attributes. The email domain needs to be in the allowed list (provided during stack creation). The email domain needs to be in the allowed list (provided during stack creation). 51 | ![](../imgs/streamlit-app-user-signup1.png) 52 | * There would be verification emailed for confirming the sign-up before the user can actually complete login. The email domain needs to match the domains (*AllowedDomains*) specified at stack creation. 53 | ![](../imgs/streamlit-app-user-signup2.png) 54 | 55 | Note: Also, one can use the Cognito Hosted UI to sign up but it does not support custom user attributes. 56 | ![](../imgs/cognito-user-signup.png) 57 | 58 | * After a valid login, one should be able to see the Welcome page. 59 | ![](../imgs/streamlit-app.png) 60 | The custom attributes used during signup are displayed in the main page and can be used to differentiate users based on their profiles. 61 | 62 | * For each of the usecase, users can select the model to run against by picking it from the drop down on the left panel. 63 | 64 | llm-models 65 | 66 | ## Cost Estimates 67 | A sample estimate of the cost of invocation (for text based models) will be reported on the left hand panel based on published cost and token estimates along with a running total of estimated costs for the current session. 68 | cost-reporting1 69 | cost-reporting2 70 | 71 | If the cost entry shows user-generated-prompt as True, it means the invocation was by done by user. If its false, then its auto-generated by the application (for coming up three or more auto-generated prompts). 72 | 73 | ## Testing 74 | Read through the instructions on the Welcome page and navigate to the various available demos on the App page or using the menu on the Left. For those samples that require submitting a sample, kindly select the model on the left hand panel, selecting a sample from the list of samples and then hit submit button. The Streamlit application would report its RUNNING on the top right corner if its still processing. Switching between different models is supported where possible; do ensure you submit the input or prompt or upload sample data as necessary for invoking the model. 75 | 76 | For the enterprise search, ensure Kendra service indexer is run against the sample artifacts so it can retrieve searches successfully. 77 | Go to the Kendra service, select the Kendra index and run `Sync` against its S3 Datasource. This will make Kendra ingest the newly uploaded sample artifacts. 78 | See Kendra documentation: https://docs.aws.amazon.com/kendra/latest/dg/data-source-s3.html for more details. 79 | 80 | ## Additional Notes 81 | * Some of the demos require various input files. A set of sample input files are available inside the **GenAISamplesArtifacts.zip** and **SearchInterpreter-Kendra.zip**, under the **sample-artifacts** directory of the Github repo. The demos have been tested with these sample files. They are automatically unzipped and uploaded during deployment into the respective s3 buckets and folders. 82 | * You can use your own files as well, but as these are only demos, the results may not be the same as the with the sample files. 83 | * For the two demos, "GenAI call analyzer" and "GenAI content analyzer": if you prefer to test with your sample dataset, upload them into the **GenAITestS3Bucket** S3 bucket and the respective directory in that bucket mapped to the corresponding demo(would be reported in the App Stack Outputs tab). For example, if you wish to the add you own sample recordings to the GenAI call analyzer demo, go the S3 bucket mapped to the **GenAITestS3Bucket** output in the CloudFormation outputs tab and click into the **call-analyzer-samples/** directory. Then upload your sample here. Go back to the demo page and refresh it. You should see your sample in the list of sample files. You can do the same for the **GenAI call analyzer** demo by uploading your samples in the **content-analyzer-samples** directory in the same bucket and refreshing the demo page. 84 | * The deployment had earlier uploaded the unzipped files from **SearchInterpreter-Kendra.zip** to the S3 Kendra Source bucket shown in the **Data Source** of the Kendra Index before running the Kendra Sync against the bucket. You can upload your own files into that bucket as well if you wish to use this demo to ask questions on your own dataset; re-run the Sync against Kendra again for the changes to be picked. 85 | * For users interested in tweaking or modifying the code, fork the repo or copy over the repository and rebuild the docker image with updated sources using CI/CD to push the changes to Fargate. 86 | 87 | Each demo has instructions and sample prompts to get started with. Please explore the art of the possible with this AWS Gen AI Demo Showcase. 88 | 89 | 90 | ### Testing with additional samples 91 | There are two buckets created to hold sample data and artifacts. One is used by S3 for all content analyzer, call analyzer and other sample use cases while other bucket is used exclusively for Kendra Search. 92 | Check the name of the buckets generated by visiting the CloudFormation Stack Outputs tab. 93 | ![](../imgs/stack-outputs-s3buckets.png) 94 | 95 | ### To test with additional sample artifacts into S3: 96 | * Go to S3 bucket specified in the Outputs tab referred as `GenAITestS3Bucket`. It would have the following structure. Any new sample content can be copied over into the `content-analyzer-samples` folder. 97 | ![](../imgs/sample-artifact-s3bucket.png) 98 | 99 | ### To test with additional sample artifacts against Kendra: 100 | * Copy over additional sample data into the Kendra's S3 bucket (referred in the Outputs tab as `GenAISearchInterpreterS3Bucket` bucket. 101 | * Then go to the Kendra service, select the Kendra index and run `Sync` against its S3 Datasource. This will make Kendra ingest the newly uploaded sample artifacts. 102 | See Kendra documentation: https://docs.aws.amazon.com/kendra/latest/dg/data-source-s3.html for more details. 103 | 104 | -------------------------------------------------------------------------------- /docs/install.md: -------------------------------------------------------------------------------- 1 | # Install 2 | 3 | * AWS CloudFormation template used for deployment will handle the creation of the sample application running the demos inside ECS Fargate and exposed over ALB with CloudFront frontending it and leveraging Cognito to handle user authentication. We recommend deploying the stack in `us-east-1` or `us-west-2` as Bedrock models and various other dependent services are mostly available here, while other regions might lack them. 4 | 5 | ![](../imgs/genai-samples-arch.png) 6 | 7 | Note: This setup allows Cognito to redirect authenicated user over to CloudFront (that has a https endpoint). Its also possible to avoid CloudFront and have Cognito authenticate and redirect to ALB but this requires custom domain and additional steps of creation of certs, etc. Please refer to [cognito-user-pool-alb-authentication](https://repost.aws/knowledge-center/cognito-user-pool-alb-authentication) for more details. 8 | 9 | ### Application Stack Deployment 10 | 11 | * To get started, download the Cloud Formation template [gen-ai-deploy-template](../cloudformation/gen-ai-deploy-template.yaml) YAML or JSON version from the [cloudformation](../cloudformation) directory of the Github repository. 12 | * Log into to your AWS account where you will be deploying this solution. 13 | * The recommended region(s) for the first phase of deployment are us-east-1 or us-west-2 as these regions support all the Amazon Bedrock models currently. If you pick any other region, you will only see the available models of that region in the list of models to pick from in the menu on the left panel for each use case. Other dependent services might also not be available. 14 | 15 | usecases 16 | 17 | * The user deploying this solution should have or assume an administrator role when possible. Admin privileges are required for the CFN script to build out the necessary roles, resources etc. 18 | * Go to the CloudFormation service console. 19 | * Select “Create Stack” > “with new resources” to create a new stack 20 | 21 | ![](../imgs/create-stack.png) 22 | 23 | * Under the “Specify Template” section, select “Upload a template file” and upload the downloaded CloudFormation template from earlier. 24 | ![](../imgs/stack-template.png) 25 | 26 | * On the next page, enter a unique name for the stack. 27 | 28 | ![](../imgs/stack-name.png) 29 | * In order to limit who can access the application, Cognito is configured to allow only specific domains to be accepted. Users who sign up have to match the allowed domains when they register their username and email address. Set the paramter *AllowedDomains* to match the list of allowed domains (can be comma separateed) for users registering. Use the *HostedUILoginURL* (would be in CloudFormation stack outputs tab) to signup for new user or use the app page to sign up as new user. Accessing the CloudFront Distribution endpoint and attempt to login will also show signup link. 30 | * Cognito user sign up supports additional custom attributes as part of the user registration to identify users by their org/dept/preferences. Edit the parameter and references to it in the template as necessary in order to customize it. 31 | * Provide a unique value for the *CognitoDomain* (so there is no overlap with any existing Cognito domains as it results in failure). Also, ensure the name does not contain *cognito* and no upper case letters. 32 | ![](../imgs/stack-details.png) 33 | * The **GenAIPublicGithubRepo** should point to the Github repository hosting this sample project by default, if not please enter the path of a forked or internally hosted repository in that section. 34 | 35 | ![](../imgs/github-repo-config.png) 36 | 37 | * The CFN template needs to access the source code for the samples, from either a github repository or from a user-managed S3 bucket. The pre-bundled source code bundle is expected to be named as **gen-ai-code.zip** (referred to as **DemoSquadGenAICodeSampleZip** parameter). 38 | 1. For the happy path with the accessible repository, the CFN script would download the source code from the Github repository and bootstap using the files for setting up the solution. 39 | 2. If your account does not have access to the publicly hosted Github repository for any reason, or unable to create private Github connections from CloudFormation, or want to deploy with custom modified sources, create **gen-ai-code.zip** from github repository separately (using `create-gen-ai-repo-zip.sh`)and then upload it into a new S3 Bucket (in same region as where the solution is being deployed). This S3 bucket name is referred to as the **GenAICodeBootstrapBucketName** in the parameters section. In this case of no access to Github repository, the CloudFormation script will download the code in zip format ( **gen-ai-code.zip**) from the specified S3 bucket. Replace the default name of the bucket associated with the parameter **GenAICodeBootstrapBucketName** with the new name of the bucket you created in the CloudFormation form. 40 | 41 | **Note:** Create and copy over the **gen-ai-code.zip** zip into the newly created S3 bucket from the Github repositary: 42 | 43 | 44 | ![](../imgs/code-sample-zip.png) 45 | 46 | * The fields shown below can be edited to have unique names as needed. They refer to the label and version of the Docker image containing the Streamlit and sample application code to be run as Fargate container. The GenAISampleECRRepo parameter would refer to the repository to be created for hosting the container images. 47 | 48 | ![](../imgs/docker-config.png) 49 | * In this version, AWS Sagemaker Jumpstart is not supported. So the below sections will not impact the deployment 50 | 51 | ![](../imgs/jumpstart.png) 52 | * In this version, we are only supporting Amazon Bedrock Titan, Anthropic Claude, Meta Llama2, and AI21 Jurassic models. Future versions will support Sagemaker Jumpstart and other models. Default is set to Anthropic Claude for any Bedrock API interactions. You can change the default selection in the template. For one of the demos, Stable Diffusion XL 1.0 on Bedrock is supported. 53 | 54 | ![](../imgs/bedrock.png) 55 | 56 | * As Sagemaker Jumpstart is not supported in this version, ignore these sections below. 57 | 58 | ![](../imgs/stable-diffusion.png) 59 | * Click “Next” through the remaining screens and acknowledge and “Submit” to start the deployment process. The deployment takes ~10-12 minutes to complete. 60 | * Once the deployment is completed, check the Outputs tab of deployed app stack. 61 | 62 | ![](../imgs/stack-output1.png) 63 | * Key Outputs: 64 | * CognitoUserPoolID: cognito user pool created to manage user auth 65 | * ECSCluster: ECS Cluster created to run the application. 66 | * ECSService: ECS Service created to run the application. 67 | * GenAISearchInterpreterS3Bucket: S3 bucket that contains search contents that can indexed by Kendra. 68 | 69 | If user is interested in modifying the samples or adding more customized usecases, this would recreation of the docker image of the streamlit app and uptaking it. There are two scripts available to recreate the ECS Docker image and push ECS to uptake the changed docker image. Edit the following scripts with correct region, stack id and run with AWS creds from command line. 70 | * `pushLatestDockerImage.sh`: shell script to push updated code as docker image for ECS. Edit the parameters as necessary before running the script. Needs AWS CLI, credentials and Docker along with access to the application code (run from directory where the *Dockerfile* exists). 71 | * `updateEcsService.sh`: shell script to update ECS to uptake any updated docker image or task definitions. Needs AWS CLI and credentials to update ECS. 72 | 73 | ![](../imgs/stack-output2.png) 74 | * HostedUILoginURL: Cognito Hosted UI Login and User Sign-up page that would then redirect back to the Streamlit app (via CloudFront url) 75 | * LBRSecureTokenHeader: Token required to communicate with the ALB (pass as `X-Custom-Header`), if user wants to test bypassing CloudFront. CloudFront passes this header during its interaction with Loadbalancer. The user auth is separate and managed via Cognito. 76 | 77 | * Check for the **GenAITestS3Bucket** key in the Outputs tab. This will refer to the newly created S3 bucket hosting readymade samples for the demo to utilize. 78 | The Cloudformation script would have already copied over required samples into this bucket for a smooth working demo. 79 | ![](../imgs/sample-artifact-s3bucket.png) 80 | 81 | * The following sample use cases are available in the first version of this solution. 82 | usecases 83 | 84 | * Check for the **KendraIndex** key in the Outputs tab. This refers to the new Kendra Index created. 85 | Go to Kendra service in console, locate the matching Kendra index and then select the Datasource (named GenAIKendraDatasource-*) on left hand panel and sync against with Kendra so it would ingest the Search interpreter demo sample contents. 86 | See Kendra documentation: https://docs.aws.amazon.com/kendra/latest/dg/data-source-s3.html for more details. 87 | 88 | ### Customizing the samples 89 | If user is interested in modifying the samples or adding more customized usecases, this would recreation of the docker image of the streamlit app and uptaking it. There are two scripts available to recreate the ECS Docker image and push ECS to uptake the changed docker image. Edit the following scripts with correct region, stack id and run with AWS creds from command line. 90 | * `pushLatestDockerImage.sh`: shell script to push updated code as docker image for ECS. Edit the parameters as necessary before running the script. Needs AWS CLI, credentials and Docker along with access to the application code (run from directory where the *Dockerfile* exists). 91 | * `updateEcsService.sh`: shell script to update ECS to uptake any updated docker image or task definitions. Needs AWS CLI and credentials to update ECS. 92 | 93 | There are two helper utiltiies that encapsulate the interactions with Bedrock and Cognito. [utils/gen_ai_selector.py](../utils/gen_ai_selector.py) handles the model selection and invocation of various Bedrock models and [utils/cognito_helper.py](../utils/cognito_helper.py) handles the user registration/signup, authentication. 94 | 95 | -------------------------------------------------------------------------------- /imgs/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/.DS_Store -------------------------------------------------------------------------------- /imgs/app-stack-output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/app-stack-output.png -------------------------------------------------------------------------------- /imgs/bedrock-access-granted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/bedrock-access-granted.png -------------------------------------------------------------------------------- /imgs/bedrock-model-accesspage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/bedrock-model-accesspage.png -------------------------------------------------------------------------------- /imgs/bedrock-models.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/bedrock-models.png -------------------------------------------------------------------------------- /imgs/bedrock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/bedrock.png -------------------------------------------------------------------------------- /imgs/cloudfront-wafv2-rules.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/cloudfront-wafv2-rules.png -------------------------------------------------------------------------------- /imgs/cloudfront-wafv2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/cloudfront-wafv2.png -------------------------------------------------------------------------------- /imgs/code-sample-zip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/code-sample-zip.png -------------------------------------------------------------------------------- /imgs/cognito-user-signup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/cognito-user-signup.png -------------------------------------------------------------------------------- /imgs/cost-reporting1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/cost-reporting1.png -------------------------------------------------------------------------------- /imgs/cost-reporting2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/cost-reporting2.png -------------------------------------------------------------------------------- /imgs/create-stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/create-stack.png -------------------------------------------------------------------------------- /imgs/docker-config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/docker-config.png -------------------------------------------------------------------------------- /imgs/enterprise-seach-kendra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/enterprise-seach-kendra.png -------------------------------------------------------------------------------- /imgs/genai-samples-arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/genai-samples-arch.png -------------------------------------------------------------------------------- /imgs/github-repo-config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/github-repo-config.png -------------------------------------------------------------------------------- /imgs/ipset-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/ipset-view.png -------------------------------------------------------------------------------- /imgs/jumpstart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/jumpstart.png -------------------------------------------------------------------------------- /imgs/llm-models.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/llm-models.png -------------------------------------------------------------------------------- /imgs/request-model-access.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/request-model-access.png -------------------------------------------------------------------------------- /imgs/sample-artifact-s3bucket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/sample-artifact-s3bucket.png -------------------------------------------------------------------------------- /imgs/sample-artifacts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/sample-artifacts.png -------------------------------------------------------------------------------- /imgs/sample-usecase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/sample-usecase.png -------------------------------------------------------------------------------- /imgs/sample-usecases.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/sample-usecases.png -------------------------------------------------------------------------------- /imgs/stable-diffusion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/stable-diffusion.png -------------------------------------------------------------------------------- /imgs/stack-details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/stack-details.png -------------------------------------------------------------------------------- /imgs/stack-name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/stack-name.png -------------------------------------------------------------------------------- /imgs/stack-output-cloudfront.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/stack-output-cloudfront.png -------------------------------------------------------------------------------- /imgs/stack-output1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/stack-output1.png -------------------------------------------------------------------------------- /imgs/stack-output2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/stack-output2.png -------------------------------------------------------------------------------- /imgs/stack-outputs-s3buckets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/stack-outputs-s3buckets.png -------------------------------------------------------------------------------- /imgs/stack-template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/stack-template.png -------------------------------------------------------------------------------- /imgs/streamlit-app-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/streamlit-app-login.png -------------------------------------------------------------------------------- /imgs/streamlit-app-user-signup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/streamlit-app-user-signup.png -------------------------------------------------------------------------------- /imgs/streamlit-app-user-signup1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/streamlit-app-user-signup1.png -------------------------------------------------------------------------------- /imgs/streamlit-app-user-signup2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/streamlit-app-user-signup2.png -------------------------------------------------------------------------------- /imgs/streamlit-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/streamlit-app.png -------------------------------------------------------------------------------- /imgs/waf-ipruleset1-no.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/waf-ipruleset1-no.png -------------------------------------------------------------------------------- /imgs/waf-ipset-allowed-cidr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/waf-ipset-allowed-cidr.png -------------------------------------------------------------------------------- /imgs/waf-stack-output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/waf-stack-output.png -------------------------------------------------------------------------------- /imgs/waf-stack-template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/waf-stack-template.png -------------------------------------------------------------------------------- /imgs/waf-stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/waf-stack.png -------------------------------------------------------------------------------- /imgs/wafv2-ipset-edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/wafv2-ipset-edit.png -------------------------------------------------------------------------------- /imgs/wafv2-ipsetrule-cidrblocks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/wafv2-ipsetrule-cidrblocks.png -------------------------------------------------------------------------------- /imgs/wafv2-ipsets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/wafv2-ipsets.png -------------------------------------------------------------------------------- /imgs/wafv2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/imgs/wafv2.png -------------------------------------------------------------------------------- /lambda-srcs/lex-fulfillment-function/lex_fulfillment.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT No Attribution 3 | 4 | Copyright 2023 Amazon Web Services 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 7 | software and associated documentation files (the "Software"), to deal in the Software 8 | without restriction, including without limitation the rights to use, copy, modify, 9 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 14 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 15 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 16 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 17 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | """ 19 | 20 | """ 21 | This sample demonstrates an implementation of the Lex Code Hook Interface 22 | in order to serve a sample bot which manages reservations for hotel rooms and car rentals. 23 | Bot, Intent, and Slot models which are compatible with this sample can be found in the Lex Console 24 | as part of the 'BookTrip' template. 25 | This sample is compatible with the Amazon Lex V2 data structure. It can be invoked as a Lambda Hook 26 | at the Fulfillment section of both intents included in the bot configuration (BookHotel and BookCar), 27 | as well as an initialization and validation function at each turn of the dialog. 28 | For instructions on how to set up and test this bot, as well as additional samples, 29 | visit the Lex Getting Started documentation http://docs.aws.amazon.com/lex/latest/dg/getting-started.html. 30 | """ 31 | 32 | import json 33 | import datetime 34 | import time 35 | import os 36 | import dateutil.parser 37 | import logging 38 | import random 39 | import string 40 | import boto3 41 | import os 42 | 43 | dynamodb = boto3.resource('dynamodb') 44 | table_name = os.environ['TABLE_NAME'] 45 | 46 | logger = logging.getLogger() 47 | logger.setLevel(logging.DEBUG) 48 | 49 | 50 | # --- Helpers that build all of the responses --- 51 | 52 | 53 | def elicit_slot(session_attributes, active_contexts, intent, slot_to_elicit, message): 54 | return { 55 | 'sessionState': { 56 | 'activeContexts':[{ 57 | 'name': 'intentContext', 58 | 'contextAttributes': active_contexts, 59 | 'timeToLive': { 60 | 'timeToLiveInSeconds': 600, 61 | 'turnsToLive': 1 62 | } 63 | }], 64 | 'sessionAttributes': session_attributes, 65 | 'dialogAction': { 66 | 'type': 'ElicitSlot', 67 | 'slotToElicit': slot_to_elicit 68 | }, 69 | 'intent': intent, 70 | } 71 | } 72 | 73 | 74 | def confirm_intent(active_contexts, session_attributes, intent, message): 75 | return { 76 | 'sessionState': { 77 | 'activeContexts': [active_contexts], 78 | 'sessionAttributes': session_attributes, 79 | 'dialogAction': { 80 | 'type': 'ConfirmIntent' 81 | }, 82 | 'intent': intent 83 | } 84 | } 85 | 86 | 87 | def close(session_attributes, active_contexts, fulfillment_state, intent, message): 88 | response = { 89 | 'sessionState': { 90 | 'activeContexts':[{ 91 | 'name': 'intentContext', 92 | 'contextAttributes': active_contexts, 93 | 'timeToLive': { 94 | 'timeToLiveInSeconds': 600, 95 | 'turnsToLive': 1 96 | } 97 | }], 98 | 'sessionAttributes': session_attributes, 99 | 'dialogAction': { 100 | 'type': 'Close', 101 | }, 102 | 'intent': intent, 103 | }, 104 | 'messages': [{'contentType': 'PlainText', 'content': message}] 105 | } 106 | 107 | return response 108 | 109 | 110 | def delegate(session_attributes, active_contexts, intent, message): 111 | return { 112 | 'sessionState': { 113 | 'activeContexts':[{ 114 | 'name': 'intentContext', 115 | 'contextAttributes': active_contexts, 116 | 'timeToLive': { 117 | 'timeToLiveInSeconds': 600, 118 | 'turnsToLive': 1 119 | } 120 | }], 121 | 'sessionAttributes': session_attributes, 122 | 'dialogAction': { 123 | 'type': 'Delegate', 124 | }, 125 | 'intent': intent, 126 | }, 127 | 'messages': [{'contentType': 'PlainText', 'content': message}] 128 | } 129 | 130 | 131 | def initial_message(intent_name): 132 | response = { 133 | 'sessionState': { 134 | 'dialogAction': { 135 | 'type': 'ElicitSlot', 136 | 'slotToElicit': 'Location' if intent_name=='BookHotel' else 'PickUpCity' 137 | }, 138 | 'intent': { 139 | 'confirmationState': 'None', 140 | 'name': intent_name, 141 | 'state': 'InProgress' 142 | } 143 | } 144 | } 145 | 146 | return response 147 | 148 | 149 | 150 | def book_hotel(intent_request): 151 | 152 | #access any session attributes you might wan to use. 153 | #session_attributes = intent_request['sessionAttributes'] if intent_request['sessionAttributes'] is not None else {} 154 | 155 | #Generate confirmation code, not guranteed to be unique, just for demo purposes. 156 | letters = random.choices(string.ascii_uppercase, k=3) 157 | digits = random.choices(string.digits, k=3) 158 | confirmation_code = ''.join(letters + digits) 159 | 160 | # Get slot values from Lex event 161 | inputMode = intent_request['inputMode'] 162 | slots = intent_request['sessionState']['intent']['slots'] 163 | comments = slots.get('ProvideComment', {}).get('value', {}).get('interpretedValue') 164 | 165 | logger.debug(comments) 166 | if comments == "Yes": 167 | logger.debug(slots.get('ProvideComment', {}).get('value', {}).get('interpretedValue')) 168 | # Construct DynamoDB item with comment 169 | item = { 170 | 'City': slots.get('City', {}).get('value', {}).get('interpretedValue'), 171 | 'CheckInDate': slots.get('CheckInDate', {}).get('value', {}).get('interpretedValue'), 172 | 'NumberOfNights': slots.get('NumberOfNights', {}).get('value', {}).get('interpretedValue'), 173 | 'NumberOfGuests': slots.get('NumberOfGuests', {}).get('value', {}).get('interpretedValue'), 174 | 'RoomType': slots.get('RoomType', {}).get('value', {}).get('interpretedValue'), 175 | 'ConfirmationCode': confirmation_code, 176 | 'Comment': slots.get('Comment', {}).get('value', {}).get('interpretedValue') 177 | } 178 | else: 179 | # Construct DynamoDB item without comment 180 | item = { 181 | 'City': slots.get('City', {}).get('value', {}).get('interpretedValue'), 182 | 'CheckInDate': slots.get('CheckInDate', {}).get('value', {}).get('interpretedValue'), 183 | 'NumberOfNights': slots.get('NumberOfNights', {}).get('value', {}).get('interpretedValue'), 184 | 'NumberOfGuests': slots.get('NumberOfGuests', {}).get('value', {}).get('interpretedValue'), 185 | 'RoomType': slots.get('RoomType', {}).get('value', {}).get('interpretedValue'), 186 | 'ConfirmationCode': confirmation_code 187 | } 188 | 189 | # Put reservation details in DynamoDB 190 | table = dynamodb.Table(table_name) 191 | table.put_item(Item=item) 192 | 193 | 194 | #Update the confirmation state, state, session attributes and active contecxt of the intent. 195 | 196 | intent = intent_request['sessionState']['intent'] 197 | 198 | session_attributes = {} ##TODO read and maintain existing attributes 199 | #session_attributes['sessionId'] = intent_request['sessionId'] 200 | 201 | if 'activeContexts' in intent_request['sessionState'] and len(intent_request['sessionState']['activeContexts']): 202 | active_contexts = intent_request['sessionState']['activeContexts'][0] 203 | else: 204 | active_contexts = {} 205 | 206 | 207 | intent['confirmationState']="Confirmed" 208 | intent['state']="Fulfilled" 209 | 210 | if inputMode == "Text": 211 | return close(session_attributes, active_contexts, 'Fulfilled', intent, 'Thanks, I have placed your reservation. Your reservation number is: ' + confirmation_code) 212 | else: 213 | return close(session_attributes, active_contexts, 'Fulfilled', intent, 'Thanks, I have placed your reservation. Your reservation number is: ' + confirmation_code[0] + ' ' + confirmation_code[1] + ' ' + confirmation_code[2] + ' ' + confirmation_code[3] + ' ' + confirmation_code[4] + ' ' + confirmation_code[5]) 214 | 215 | 216 | # --- Intents --- 217 | 218 | 219 | def dispatch(intent_request): 220 | """ 221 | The dispatcher calls the relecant code for the intent that we are trying to fulfill. 222 | """ 223 | logger.debug(intent_request) 224 | 225 | #We check which intent is used 226 | intent_name = intent_request['sessionState']['intent']['name'] 227 | 228 | 229 | # Dispatch to your bot's intent handlers. Add additional intent handlers for any additional intents that are implemented 230 | if intent_name == 'BookHotel': 231 | return book_hotel(intent_request) 232 | 233 | raise Exception('Intent with name ' + intent_name + ' not supported') 234 | 235 | 236 | # --- Main handler --- 237 | 238 | 239 | def lambda_handler(event, context): 240 | """ 241 | Route the incoming request based on intent. 242 | The JSON body of the request is provided in the event slot. 243 | """ 244 | # By default, treat the user request as coming from the America/New_York time zone. 245 | os.environ['TZ'] = 'America/New_York' 246 | time.tzset() 247 | logger.debug('event.bot.name={}'.format(event['bot']['name'])) 248 | logger.debug(event) 249 | return dispatch(event) -------------------------------------------------------------------------------- /lambda-srcs/lex-fulfillment-function/requirements.txt: -------------------------------------------------------------------------------- 1 | urllib3==1.26.6 2 | requests==2.27.1 3 | -------------------------------------------------------------------------------- /lambda-srcs/lex-fulfillment-function/template.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Transform: AWS::Serverless-2016-10-31 3 | Description: > 4 | lex-fulfillment-lambda 5 | 6 | Sample SAM Template for lex-fulfillment-lambda 7 | 8 | # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst 9 | Globals: 10 | Function: 11 | Timeout: 30 12 | MemorySize: 128 13 | 14 | Resources: 15 | LexFulfillmentFunction: 16 | Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction 17 | Properties: 18 | Handler: lex_fulfillment.lambda_handler 19 | Runtime: python3.9 20 | Architectures: 21 | - x86_64 22 | Outputs: 23 | # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function 24 | # Find out more about other implicit resources you can reference within SAM 25 | # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api 26 | 27 | LexFulfillmentFunction: 28 | Description: "Lex Fulfillment Lambda Function ARN" 29 | Value: !GetAtt LexFulfillmentFunction.Arn 30 | LexFulfillmentFunctionIamRole: 31 | Description: "Implicit IAM Role created for Lex Fulfillment function" 32 | Value: !GetAtt LexFulfillmentFunctionRole.Arn 33 | 34 | -------------------------------------------------------------------------------- /lambda-srcs/lex-rag-lambda-function/requirements.txt: -------------------------------------------------------------------------------- 1 | urllib3==1.26.6 2 | requests==2.27.1 3 | s3transfer==0.10 4 | six==1.16.0 5 | jmespath==1.0.1 6 | -------------------------------------------------------------------------------- /lambda-srcs/lex-rag-lambda-function/samconfig.toml.BAK: -------------------------------------------------------------------------------- 1 | version = 0.1 2 | [default] 3 | [default.deploy] 4 | [default.deploy.parameters] 5 | stack_name = "lexbot-rag2" 6 | s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-1mj37idniykfg" 7 | s3_prefix = "lexbot-rag2" 8 | region = "us-west-2" 9 | capabilities = "CAPABILITY_IAM" 10 | image_repositories = [] 11 | -------------------------------------------------------------------------------- /lambda-srcs/lex-rag-lambda-function/template.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Transform: AWS::Serverless-2016-10-31 3 | Description: > 4 | lexbot-rag-lambda 5 | 6 | Sample SAM Template for lexbot-rag-lambda 7 | 8 | # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst 9 | Globals: 10 | Function: 11 | Timeout: 30 12 | MemorySize: 128 13 | 14 | Resources: 15 | LexBotRagFunction: 16 | Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction 17 | Properties: 18 | Handler: lexbot_rag.lambda_handler 19 | Runtime: python3.9 20 | Architectures: 21 | - x86_64 22 | Outputs: 23 | # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function 24 | # Find out more about other implicit resources you can reference within SAM 25 | # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api 26 | 27 | LexBotRagFunction: 28 | Description: "LexBot Rag Lambda Function ARN" 29 | Value: !GetAtt LexBotRagFunction.Arn 30 | LexBotRagFunctionIamRole: 31 | Description: "Implicit IAM Role created for LexBot Rag function" 32 | Value: !GetAtt LexBotRagFunctionRole.Arn 33 | 34 | -------------------------------------------------------------------------------- /lambda-srcs/s3-bucket-cleanup-function/requirements.txt: -------------------------------------------------------------------------------- 1 | urllib3==1.26.6 2 | requests==2.27.1 3 | -------------------------------------------------------------------------------- /lambda-srcs/s3-bucket-cleanup-function/s3_bucket_cleanup.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT No Attribution 3 | 4 | Copyright 2023 Amazon Web Services 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 7 | software and associated documentation files (the "Software"), to deal in the Software 8 | without restriction, including without limitation the rights to use, copy, modify, 9 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 14 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 15 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 16 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 17 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | """ 19 | 20 | import json 21 | import boto3 22 | 23 | import requests 24 | 25 | # Reference code from 26 | # https://gist.github.com/drumadrian/e1601ab34e7f609b5075f65599108960#file-custom-cloudformation-bucket-cleanup-yaml-L99-L103 27 | def lambda_handler(event, context): 28 | 29 | try: 30 | bucketName = event['ResourceProperties']['BucketName'] 31 | if event['RequestType'] == 'Delete': 32 | s3 = boto3.resource('s3') 33 | bucket = s3.Bucket(bucketName) 34 | for obj in bucket.objects.filter(): 35 | s3.Object(bucket.name, obj.key).delete() 36 | sendResponse(event, context, "SUCCESS") 37 | except Exception as e: 38 | print(e) 39 | sendResponse(event, context, "FAILED") 40 | 41 | def sendResponse(event, context, responseStatus): 42 | response_body = {'Status': responseStatus, 43 | 'Reason': 'Log stream name: ' + context.log_stream_name, 44 | 'PhysicalResourceId': context.log_stream_name, 45 | 'StackId': event['StackId'], 46 | 'RequestId': event['RequestId'], 47 | 'LogicalResourceId': event['LogicalResourceId'], 48 | 'Data': json.loads("{}")} 49 | requests.put(event['ResponseURL'], data=json.dumps(response_body)) 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /lambda-srcs/s3-bucket-cleanup-function/template.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Transform: AWS::Serverless-2016-10-31 3 | Description: > 4 | s3-cleanup-lambda 5 | 6 | Sample SAM Template for s3-cleanup-lambda 7 | 8 | # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst 9 | Globals: 10 | Function: 11 | Timeout: 180 12 | MemorySize: 128 13 | 14 | Resources: 15 | S3BucketCleanupFunction: 16 | Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction 17 | Properties: 18 | #CodeUri: waf-ops-s3bucket-10kk81dvkt5of #s3_bucket_cleanup_function/ 19 | Handler: s3_bucket_cleanup.lambda_handler 20 | Runtime: python3.9 21 | Architectures: 22 | - x86_64 23 | Outputs: 24 | # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function 25 | # Find out more about other implicit resources you can reference within SAM 26 | # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api 27 | 28 | S3BucketCleanupFunction: 29 | Description: "S3 Bucket Cleanup Lambda Function ARN" 30 | Value: !GetAtt S3BucketCleanupFunction.Arn 31 | S3BucketCleanupFunctionIamRole: 32 | Description: "Implicit IAM Role created for S3 Bucket Cleanup function" 33 | Value: !GetAtt S3BucketCleanupFunctionRole.Arn 34 | 35 | -------------------------------------------------------------------------------- /lambda-srcs/sagemaker-deployer-function/repo_parser.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT No Attribution 3 | 4 | Copyright 2023 Amazon Web Services 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 7 | software and associated documentation files (the "Software"), to deal in the Software 8 | without restriction, including without limitation the rights to use, copy, modify, 9 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 14 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 15 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 16 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 17 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | """ 19 | 20 | # This utility is to parse AI21 sageamkaer relaeted files from the public AI21 github repo (https://github.com/AI21Labs/SageMaker 21 | # to pull Sagemaker related Model ARN and recommended instance type (or first provided instance type for inference) 22 | # The parsed content is already saved as a json file (ai21_model_package_arns.json) for quick reference 23 | 24 | from github import Github 25 | import os 26 | import requests 27 | import re 28 | import json 29 | 30 | 31 | ai21_map = {} 32 | 33 | LOCAL_FILE_REPO = '/home/ec2-user/environment/workspace/AI21-SM/' 34 | 35 | REPO = "AI21Labs/SageMaker" 36 | FULL_REPO = f'https://github.com/{REPO}' 37 | RAW_FULL_REPO = f'https://raw.githubusercontent.com/{REPO}' 38 | 39 | def check_sagemaker_arns_and_instance(filePath): 40 | #print( 'Processing raw file: ' + f'{RAW_FULL_REPO}/main/{filePath}') 41 | content = requests.get(f'{RAW_FULL_REPO}/main/{filePath}', stream=True) 42 | 43 | arn_entries = {} 44 | instance_type = '' 45 | 46 | recommended_instance = None 47 | for line in content.iter_lines(): 48 | line_str = str(line) 49 | #print(line_str) 50 | 51 | if 'arn:aws:sagemaker' in line_str: 52 | start = line_str.index('\\') 53 | len_str = len(line_str) 54 | end = line_str.index('\\', len_str - 10) 55 | arn_entry = line_str[start:end+3].replace('\\', '') 56 | #print(arn_entry) 57 | index = arn_entry.index(':') 58 | region = arn_entry[0:index - 1].replace('"', '') 59 | arn_entries[region] = arn_entry[index+1:].replace('"', '').replace(',', '').strip() 60 | #print('arn path: ', arn_entry[index+1:]) 61 | elif 'Recommended instance' in line_str: 62 | #print(line_str) 63 | recommended_instance = line_str 64 | elif '"instance_type"' in line_str: 65 | #print(line_str) 66 | instance_type = line_str 67 | 68 | if recommended_instance != None: 69 | instance_type = recommended_instance 70 | 71 | instance_type = re.sub('# .*', '', instance_type).replace('\\', '').replace('b\'', '').replace('"', '').replace(',', '').strip() 72 | #print('Final Instnace type:', instance_type) 73 | 74 | #print(arn_entries) 75 | #print(instance_type) 76 | 77 | final_model_package = { 'model_package_map': arn_entries, 'instance_type': instance_type } 78 | return final_model_package 79 | 80 | def check_local(filePath): 81 | #print('checking local file:', filePath) 82 | file1 = open(filePath, 'r') 83 | lines = file1.readlines() 84 | 85 | arn_entries = {} 86 | instance_type = '' 87 | 88 | recommended_instance = None 89 | for line in lines: 90 | line_str = str(line) 91 | if 'arn:aws:sagemaker' in line_str: 92 | start = line_str.index('\\') 93 | len_str = len(line_str) 94 | end = line_str.index('\\', len_str - 10) 95 | arn_entry = line_str[start:end+3].replace('\\n', '').replace('\\', '') 96 | #print(arn_entry) 97 | index = arn_entry.index(':') 98 | region = arn_entry[0:index - 1].replace('"', '') 99 | arn_entries[region] = arn_entry[index+1:].replace('"', '').replace(',', '').strip() 100 | #print('arn path: ', arn_entry[index+1:]) 101 | elif 'Recommended instance' in line_str: 102 | #print(line_str) 103 | recommended_instance = line_str 104 | elif ( 'ml' in line_str and 'large' in line_str and instance_type == '' ): 105 | instance_type = line_str 106 | #instance_type = re.sub('# .*', '', line_str).replace('\\n', '').replace('\\', '').replace('"', '').replace(',', '').strip() 107 | #print(instance_type) 108 | 109 | if recommended_instance != None: 110 | instance_type = recommended_instance 111 | 112 | instance_type = re.sub('# .*', '', instance_type).replace('\\n', '').replace('\\', '').replace('"', '').replace(',', '').strip() 113 | #print('Recommended Instance type:', instance_type) 114 | 115 | #print(arn_entries) 116 | #print(instance_type) 117 | 118 | final_model_package = { 'model_package_map': arn_entries, 'instance_type': instance_type } 119 | return final_model_package 120 | 121 | def create_model_package_map_from_github(): 122 | g = Github() 123 | repo = g.get_repo(REPO) 124 | 125 | for file in repo.get_contents("."): 126 | #print(file.name) 127 | if ('.ipynb' in file.name): 128 | model_name = 'ai21.' + file.lower().replace('_example_model_use.ipynb', '').replace('_', '-') 129 | model_map_entry = { 'model': model_name, 'model_package_map': [ ] } 130 | parsed_package_map = check_sagemaker_arns_and_instance(file.name) 131 | if len(parsed_package_map['model_package_map']) != 0: 132 | model_map_entry['model_package_map'] = parsed_package_map['model_package_map'] 133 | model_map_entry['instance_type'] = parsed_package_map['instance_type'] 134 | ai21_map[model_name] = model_map_entry 135 | 136 | return ai21_map 137 | 138 | # For local file testing 139 | def create_model_package_map_from_local_files(): 140 | for file in [ 141 | 'AI21_ContextualAnswers_example_model_use.ipynb', 'AI21_Summarize_example_model_use.ipynb', 'J2_GrandeInstruct_example_model_use.ipynb', 'J2_Large_example_model_use.ipynb', 'J2_Ultra_example_model_use.ipynb', 142 | 'AI21_GEC_example_model_use.ipynb', 'J1_Grande_example_model_use.ipynb', 'J2_Jumbo_example_model_use.ipynb', 'J2_Light_example_model_use.ipynb', 143 | 'AI21_Paraphrase_example_model_use.ipynb', 'J2_Grande_example_model_use.ipynb', 'J2_JumboInstruct_example_model_use.ipynb', 'J2_Mid_example_model_use.ipynb' ]: 144 | #print(file) 145 | model_name = 'ai21.' + file.lower().replace('_example_model_use.ipynb', '').replace('_', '-') 146 | model_map_entry = { 'model': model_name, 'model_package_map': [ ] } 147 | #check_sagemaker_arns_and_instance(file.name 148 | parsed_package_map = check_local(LOCAL_FILE_REPO + file) 149 | if len(parsed_package_map['model_package_map']) != 0: 150 | model_map_entry['model_package_map'] = parsed_package_map['model_package_map'] 151 | model_map_entry['instance_type'] = parsed_package_map['instance_type'] 152 | ai21_map[model_name] = model_map_entry 153 | 154 | return ai21_map 155 | 156 | 157 | #create_model_package_map_from_github() 158 | create_model_package_map_from_local_files() 159 | #print(ai21_map) 160 | print() 161 | #print(json.dumps(ai21_map)) 162 | #exit(-1) 163 | 164 | # Test 165 | script_dir = os.path.dirname(__file__) #<-- absolute dir the script is in 166 | ai21_model_package_defn = 'ai21_model_package_arns.json' 167 | ai21_model_package_path = os.path.join(script_dir, ai21_model_package_defn) 168 | model_package_file = open(ai21_model_package_path) 169 | ai21_model_package_json = json.load(model_package_file) 170 | print('loaded json:') 171 | 172 | model_id='ai21.j1-grande' 173 | region='us-east-1' 174 | if model_id.startswith('ai21'): 175 | print(ai21_model_package_json[model_id]) 176 | print(ai21_model_package_json[model_id]['model_package_map'][region]) 177 | -------------------------------------------------------------------------------- /lambda-srcs/sagemaker-deployer-function/requirements.txt: -------------------------------------------------------------------------------- 1 | sagemaker 2 | PyGithub 3 | urllib3==1.26.6 4 | requests==2.27.1 -------------------------------------------------------------------------------- /lambda-srcs/sagemaker-deployer-function/template.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Transform: 'AWS::Serverless-2016-10-31' 3 | Description: An AWS Serverless Specification template describing your function. 4 | Resources: 5 | SageMakerDeployerFunction: 6 | Type: 'AWS::Serverless::Function' 7 | Properties: 8 | Handler: deployer.lambda_handler 9 | Runtime: python3.9 10 | Description: '' 11 | MemorySize: 128 12 | Timeout: 900 13 | RuntimeManagementConfig: 14 | UpdateRuntimeOn: Auto 15 | 16 | -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/Bot.json: -------------------------------------------------------------------------------- 1 | {"name":"GenAIHotelBookingLexChatbot","version":"DRAFT","description":"This is a bot for booking a hotel room and managing cancelling reservations.","identifier":"XEDEG8PEOH","errorLogSettings":null,"dataPrivacy":{"childDirected":false},"idleSessionTTLInSeconds":300} -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/BotLocales/en_US/BotLocale.json: -------------------------------------------------------------------------------- 1 | {"name":"English (US)","identifier":"en_US","version":null,"description":null,"voiceSettings":{"engine":"neural","voiceId":"Matthew"},"nluConfidenceThreshold":0.7,"generativeAISettings":{"buildtimeSettings":{"descriptiveBotBuilderSpecification":{"enabled":true,"bedrockModelSpecification":{"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-v2","customPrompt":null,"bedrockGuardrailConfiguration":null,"bedrockTraceStatus":null}},"sampleUtteranceGenerationSpecification":{"enabled":true,"bedrockModelSpecification":{"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-v2","customPrompt":null,"bedrockGuardrailConfiguration":null,"bedrockTraceStatus":null}}},"runtimeSettings":{"slotResolutionImprovementSpecification":{"enabled":true,"bedrockModelSpecification":{"modelArn":"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-v2","customPrompt":null,"bedrockGuardrailConfiguration":null,"bedrockTraceStatus":null}}}}} -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/BotLocales/en_US/Intents/BookHotel/ConversationFlow.json: -------------------------------------------------------------------------------- 1 | {"intentName":"BookHotel","identifier":"CONVFLOWID","conversationFlowData":{"metadata":{"schemaVersion":"1","dataFormat":"JSON"},"blocks":[{"blockType":"StartIntent","dataLocations":["intent/StartIntent_"],"blockId":"startintent","coordinate":{"x":"200","y":"400"}},{"blockType":"GetSlotValue","dataLocations":["intent/GetSlotValue-City_"],"blockId":"getslotvalue_City","coordinate":{"x":"470","y":"396"}},{"blockType":"GetSlotValue","dataLocations":["intent/GetSlotValue-CheckInDate_"],"blockId":"getslotvalue_CheckInDate","coordinate":{"x":"793","y":"398"}},{"blockType":"GoToIntent","dataLocations":["intent/GetSlotValue-City_/GoToIntent-FallbackIntent_ns_GetSlotValueFailure","intent/GetSlotValue-CheckInDate_/GoToIntent-FallbackIntent_ns_GetSlotValueFailure","intent/GetSlotValue-NumberOfNights_/GoToIntent-FallbackIntent_ns_GetSlotValueFailure","intent/GetSlotValue-RoomType_/GoToIntent-FallbackIntent_ns_GetSlotValueFailure","intent/GetSlotValue-NumberOfGuests_/GoToIntent-FallbackIntent_ns_GetSlotValueFailure","intent/GetSlotValue-_/GoToIntent-FallbackIntent_ns_GetSlotValueFailure","intent/GetSlotValue-_/GoToIntent-FallbackIntent_ns_GetSlotValueFailure","intent/Confirmation_/GoToIntent-FallbackIntent_ns_ConfirmationFailure","intent/Fulfillment_/GoToIntent-FallbackIntent_ns_FulfillmentTimeout","intent/Fulfillment_/GoToIntent-FallbackIntent_ns_FulfillmentError"],"blockId":"gotointent_FallbackIntent_ns","coordinate":{"x":"3889","y":"805"}},{"blockType":"GetSlotValue","dataLocations":["intent/GetSlotValue-NumberOfNights_"],"blockId":"getslotvalue_NumberOfNights","coordinate":{"x":"1139","y":"400"}},{"blockType":"GetSlotValue","dataLocations":["intent/GetSlotValue-RoomType_"],"blockId":"getslotvalue_RoomType","coordinate":{"x":"1473","y":"393"}},{"blockType":"GetSlotValue","dataLocations":["intent/GetSlotValue-NumberOfGuests_"],"blockId":"getslotvalue_NumberOfGuests","coordinate":{"x":"1804","y":"394"}},{"blockType":"GetSlotValue","dataLocations":["intent/GetSlotValue-_"],"blockId":"dm-node-ab7d054a-1abc-46ee-9cb3-78ba9b3e3459","coordinate":{"x":"2136","y":"397"}},{"blockType":"Condition","dataLocations":["intent/GetSlotValue-_/Condition_GetSlotValueSuccess"],"blockId":"dm-node-08bfa342-56cb-4f19-9474-3d6aa8080d9d","coordinate":{"x":"2469","y":"397"}},{"blockType":"Confirmation","dataLocations":["intent/Confirmation_"],"blockId":"dm-node-99e512e4-6030-429a-ab5c-8cef668627e6","coordinate":{"x":"3145","y":"399"}},{"blockType":"GetSlotValue","dataLocations":["intent/GetSlotValue-_"],"blockId":"dm-node-11442335-3ff4-44e1-b332-c562a956d6c6","coordinate":{"x":"2808","y":"400"}},{"blockType":"Fulfillment","dataLocations":["intent/Fulfillment_"],"blockId":"dm-node-c437613b-a69e-4324-b9bd-e1e873f43427","coordinate":{"x":"3469","y":"401"}},{"blockType":"End","dataLocations":["intent/Fulfillment_/End_FulfillmentSuccess"],"blockId":"end","coordinate":{"x":"3872","y":"400"}}],"edges":[{"vertices":[{"x":"725","y":"611"},{"x":"725","y":"681"},{"x":"725","y":"751"},{"x":"725","y":"821"},{"x":"795","y":"821"},{"x":"865","y":"821"},{"x":"935","y":"821"},{"x":"1005","y":"821"},{"x":"1075","y":"821"},{"x":"1145","y":"821"},{"x":"1215","y":"821"},{"x":"1285","y":"821"},{"x":"1355","y":"821"},{"x":"1425","y":"821"},{"x":"1495","y":"821"},{"x":"1565","y":"821"},{"x":"1635","y":"821"},{"x":"1705","y":"821"},{"x":"1775","y":"821"},{"x":"1845","y":"821"},{"x":"1915","y":"821"},{"x":"1985","y":"821"},{"x":"2055","y":"821"},{"x":"2125","y":"821"},{"x":"2195","y":"821"},{"x":"2265","y":"821"},{"x":"2335","y":"821"},{"x":"2405","y":"821"},{"x":"2475","y":"821"},{"x":"2545","y":"821"},{"x":"2615","y":"821"},{"x":"2685","y":"821"},{"x":"2755","y":"821"},{"x":"2825","y":"821"},{"x":"2895","y":"821"},{"x":"2965","y":"821"},{"x":"3035","y":"821"},{"x":"3105","y":"821"},{"x":"3175","y":"821"},{"x":"3245","y":"821"},{"x":"3315","y":"821"},{"x":"3385","y":"821"},{"x":"3455","y":"821"},{"x":"3525","y":"821"},{"x":"3595","y":"821"},{"x":"3665","y":"821"},{"x":"3735","y":"821"},{"x":"3805","y":"821"},{"x":"3805","y":"822"},{"x":"3874","y":"822"}],"edgeLocation":"intent/GetSlotValue-_/GoToIntent-FallbackIntent_ns_GetSlotValueFailure","originBlockId":"getslotvalue_City","destinationBlockId":"gotointent_FallbackIntent_ns","originBlockPort":"GetSlotValueFailure","destinationBlockPort":"GoToIntentInput"},{"vertices":[{"x":"1048","y":"613"},{"x":"1118","y":"613"},{"x":"1118","y":"683"},{"x":"1118","y":"753"},{"x":"1118","y":"823"},{"x":"1188","y":"823"},{"x":"1258","y":"823"},{"x":"1328","y":"823"},{"x":"1398","y":"823"},{"x":"1468","y":"823"},{"x":"1538","y":"823"},{"x":"1608","y":"823"},{"x":"1678","y":"823"},{"x":"1748","y":"823"},{"x":"1818","y":"823"},{"x":"1888","y":"823"},{"x":"1958","y":"823"},{"x":"2028","y":"823"},{"x":"2098","y":"823"},{"x":"2168","y":"823"},{"x":"2238","y":"823"},{"x":"2308","y":"823"},{"x":"2378","y":"823"},{"x":"2448","y":"823"},{"x":"2518","y":"823"},{"x":"2588","y":"823"},{"x":"2658","y":"823"},{"x":"2728","y":"823"},{"x":"2798","y":"823"},{"x":"2868","y":"823"},{"x":"2938","y":"823"},{"x":"3008","y":"823"},{"x":"3078","y":"823"},{"x":"3148","y":"823"},{"x":"3218","y":"823"},{"x":"3288","y":"823"},{"x":"3358","y":"823"},{"x":"3428","y":"823"},{"x":"3498","y":"823"},{"x":"3568","y":"823"},{"x":"3638","y":"823"},{"x":"3708","y":"823"},{"x":"3778","y":"823"},{"x":"3848","y":"823"},{"x":"3848","y":"822"},{"x":"3874","y":"822"}],"edgeLocation":"intent/GetSlotValue-_/GoToIntent-FallbackIntent_ns_GetSlotValueFailure","originBlockId":"getslotvalue_CheckInDate","destinationBlockId":"gotointent_FallbackIntent_ns","originBlockPort":"GetSlotValueFailure","destinationBlockPort":"GoToIntentInput"},{"vertices":[{"x":"1394","y":"615"},{"x":"1464","y":"615"},{"x":"1464","y":"685"},{"x":"1464","y":"755"},{"x":"1464","y":"825"},{"x":"1534","y":"825"},{"x":"1604","y":"825"},{"x":"1674","y":"825"},{"x":"1744","y":"825"},{"x":"1814","y":"825"},{"x":"1884","y":"825"},{"x":"1954","y":"825"},{"x":"2024","y":"825"},{"x":"2094","y":"825"},{"x":"2164","y":"825"},{"x":"2234","y":"825"},{"x":"2304","y":"825"},{"x":"2374","y":"825"},{"x":"2444","y":"825"},{"x":"2514","y":"825"},{"x":"2584","y":"825"},{"x":"2654","y":"825"},{"x":"2724","y":"825"},{"x":"2794","y":"825"},{"x":"2864","y":"825"},{"x":"2934","y":"825"},{"x":"3004","y":"825"},{"x":"3074","y":"825"},{"x":"3144","y":"825"},{"x":"3214","y":"825"},{"x":"3284","y":"825"},{"x":"3354","y":"825"},{"x":"3424","y":"825"},{"x":"3494","y":"825"},{"x":"3564","y":"825"},{"x":"3634","y":"825"},{"x":"3704","y":"825"},{"x":"3774","y":"825"},{"x":"3844","y":"825"},{"x":"3844","y":"822"},{"x":"3874","y":"822"}],"edgeLocation":"intent/GetSlotValue-_/GoToIntent-FallbackIntent_ns_GetSlotValueFailure","originBlockId":"getslotvalue_NumberOfNights","destinationBlockId":"gotointent_FallbackIntent_ns","originBlockPort":"GetSlotValueFailure","destinationBlockPort":"GoToIntentInput"},{"vertices":[{"x":"1728","y":"608"},{"x":"1798","y":"608"},{"x":"1798","y":"678"},{"x":"1798","y":"748"},{"x":"1798","y":"818"},{"x":"1868","y":"818"},{"x":"1938","y":"818"},{"x":"2008","y":"818"},{"x":"2078","y":"818"},{"x":"2148","y":"818"},{"x":"2218","y":"818"},{"x":"2288","y":"818"},{"x":"2358","y":"818"},{"x":"2428","y":"818"},{"x":"2498","y":"818"},{"x":"2568","y":"818"},{"x":"2638","y":"818"},{"x":"2708","y":"818"},{"x":"2778","y":"818"},{"x":"2848","y":"818"},{"x":"2918","y":"818"},{"x":"2988","y":"818"},{"x":"3058","y":"818"},{"x":"3128","y":"818"},{"x":"3198","y":"818"},{"x":"3268","y":"818"},{"x":"3338","y":"818"},{"x":"3408","y":"818"},{"x":"3478","y":"818"},{"x":"3548","y":"818"},{"x":"3618","y":"818"},{"x":"3688","y":"818"},{"x":"3758","y":"818"},{"x":"3828","y":"818"},{"x":"3828","y":"822"},{"x":"3874","y":"822"}],"edgeLocation":"intent/GetSlotValue-_/GoToIntent-FallbackIntent_ns_GetSlotValueFailure","originBlockId":"getslotvalue_RoomType","destinationBlockId":"gotointent_FallbackIntent_ns","originBlockPort":"GetSlotValueFailure","destinationBlockPort":"GoToIntentInput"},{"vertices":[{"x":"2059","y":"609"},{"x":"2129","y":"609"},{"x":"2129","y":"679"},{"x":"2129","y":"749"},{"x":"2129","y":"819"},{"x":"2199","y":"819"},{"x":"2269","y":"819"},{"x":"2339","y":"819"},{"x":"2409","y":"819"},{"x":"2479","y":"819"},{"x":"2549","y":"819"},{"x":"2619","y":"819"},{"x":"2689","y":"819"},{"x":"2759","y":"819"},{"x":"2829","y":"819"},{"x":"2899","y":"819"},{"x":"2969","y":"819"},{"x":"3039","y":"819"},{"x":"3109","y":"819"},{"x":"3179","y":"819"},{"x":"3249","y":"819"},{"x":"3319","y":"819"},{"x":"3389","y":"819"},{"x":"3459","y":"819"},{"x":"3529","y":"819"},{"x":"3599","y":"819"},{"x":"3669","y":"819"},{"x":"3739","y":"819"},{"x":"3809","y":"819"},{"x":"3809","y":"822"},{"x":"3874","y":"822"}],"edgeLocation":"intent/GetSlotValue-_/GoToIntent-FallbackIntent_ns_GetSlotValueFailure","originBlockId":"getslotvalue_NumberOfGuests","destinationBlockId":"gotointent_FallbackIntent_ns","originBlockPort":"GetSlotValueFailure","destinationBlockPort":"GoToIntentInput"},{"vertices":[{"x":"2391","y":"572"},{"x":"2461","y":"572"},{"x":"2461","y":"502"},{"x":"2461","y":"432"},{"x":"2461","y":"414"},{"x":"2454","y":"414"}],"edgeLocation":"intent/GetSlotValue-_/Condition_GetSlotValueSuccess","originBlockId":"dm-node-ab7d054a-1abc-46ee-9cb3-78ba9b3e3459","destinationBlockId":"dm-node-08bfa342-56cb-4f19-9474-3d6aa8080d9d","originBlockPort":"GetSlotValueSuccess","destinationBlockPort":"ConditionInput"},{"vertices":[{"x":"2391","y":"612"},{"x":"2461","y":"612"},{"x":"2461","y":"682"},{"x":"2461","y":"752"},{"x":"2461","y":"822"},{"x":"2531","y":"822"},{"x":"2601","y":"822"},{"x":"2671","y":"822"},{"x":"2741","y":"822"},{"x":"2811","y":"822"},{"x":"2881","y":"822"},{"x":"2951","y":"822"},{"x":"3021","y":"822"},{"x":"3091","y":"822"},{"x":"3161","y":"822"},{"x":"3231","y":"822"},{"x":"3301","y":"822"},{"x":"3371","y":"822"},{"x":"3441","y":"822"},{"x":"3511","y":"822"},{"x":"3581","y":"822"},{"x":"3651","y":"822"},{"x":"3721","y":"822"},{"x":"3791","y":"822"},{"x":"3861","y":"822"},{"x":"3874","y":"822"}],"edgeLocation":"intent/GetSlotValue-_/GoToIntent-FallbackIntent_ns_GetSlotValueFailure","originBlockId":"dm-node-ab7d054a-1abc-46ee-9cb3-78ba9b3e3459","destinationBlockId":"gotointent_FallbackIntent_ns","originBlockPort":"GetSlotValueFailure","destinationBlockPort":"GoToIntentInput"},{"vertices":[{"x":"3063","y":"615"},{"x":"3133","y":"615"},{"x":"3133","y":"685"},{"x":"3133","y":"755"},{"x":"3133","y":"825"},{"x":"3203","y":"825"},{"x":"3273","y":"825"},{"x":"3343","y":"825"},{"x":"3413","y":"825"},{"x":"3483","y":"825"},{"x":"3553","y":"825"},{"x":"3623","y":"825"},{"x":"3693","y":"825"},{"x":"3763","y":"825"},{"x":"3833","y":"825"},{"x":"3833","y":"822"},{"x":"3874","y":"822"}],"edgeLocation":"intent/GetSlotValue-_/GoToIntent-FallbackIntent_ns_GetSlotValueFailure","originBlockId":"dm-node-11442335-3ff4-44e1-b332-c562a956d6c6","destinationBlockId":"gotointent_FallbackIntent_ns","originBlockPort":"GetSlotValueFailure","destinationBlockPort":"GoToIntentInput"},{"vertices":[{"x":"3400","y":"649"},{"x":"3400","y":"719"},{"x":"3400","y":"789"},{"x":"3470","y":"789"},{"x":"3540","y":"789"},{"x":"3610","y":"789"},{"x":"3680","y":"789"},{"x":"3750","y":"789"},{"x":"3820","y":"789"},{"x":"3820","y":"822"},{"x":"3874","y":"822"}],"edgeLocation":"intent/Confirmation_/GoToIntent-FallbackIntent_ns_ConfirmationFailure","originBlockId":"dm-node-99e512e4-6030-429a-ab5c-8cef668627e6","destinationBlockId":"gotointent_FallbackIntent_ns","originBlockPort":"ConfirmationFailure","destinationBlockPort":"GoToIntentInput"},{"vertices":[{"x":"3724","y":"561"},{"x":"3794","y":"561"},{"x":"3864","y":"561"},{"x":"3864","y":"491"},{"x":"3864","y":"421"},{"x":"3864","y":"417"},{"x":"3857","y":"417"}],"edgeLocation":"intent/Fulfillment_/End_FulfillmentSuccess","originBlockId":"dm-node-c437613b-a69e-4324-b9bd-e1e873f43427","destinationBlockId":"end","originBlockPort":"FulfillmentSuccess","destinationBlockPort":"EndConversationInput"},{"vertices":[{"x":"3724","y":"641"},{"x":"3794","y":"641"},{"x":"3864","y":"641"},{"x":"3864","y":"711"},{"x":"3864","y":"781"},{"x":"3864","y":"822"},{"x":"3874","y":"822"}],"edgeLocation":"intent/Fulfillment_/GoToIntent-FallbackIntent_ns_FulfillmentTimeout","originBlockId":"dm-node-c437613b-a69e-4324-b9bd-e1e873f43427","destinationBlockId":"gotointent_FallbackIntent_ns","originBlockPort":"FulfillmentTimeout","destinationBlockPort":"GoToIntentInput"},{"vertices":[{"x":"3724","y":"601"},{"x":"3794","y":"601"},{"x":"3864","y":"601"},{"x":"3864","y":"671"},{"x":"3864","y":"741"},{"x":"3864","y":"811"},{"x":"3864","y":"822"},{"x":"3874","y":"822"}],"edgeLocation":"intent/Fulfillment_/GoToIntent-FallbackIntent_ns_FulfillmentError","originBlockId":"dm-node-c437613b-a69e-4324-b9bd-e1e873f43427","destinationBlockId":"gotointent_FallbackIntent_ns","originBlockPort":"FulfillmentError","destinationBlockPort":"GoToIntentInput"}]}} -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/BotLocales/en_US/Intents/BookHotel/Intent.json: -------------------------------------------------------------------------------- 1 | {"name":"BookHotel","identifier":"8FF4SDYB0O","description":null,"parentIntentSignature":null,"sampleUtterances":[{"utterance":"I would like you to book a hotel for me in {City}"},{"utterance":"Could you book a hotel room for me in {City}"},{"utterance":"Get me a hotel room in {City} checking in on {CheckInDate}"},{"utterance":"Please book me a hotel in {City} for {NumberOfNights} checing in {CheckInDate}"},{"utterance":"I want to book a hotel in {City}"},{"utterance":"Book me a hotel room in {City} for {NumberOfNights} nights."},{"utterance":"Can you book a hotel for me in {City}"},{"utterance":"Please book a hotel room for me in {City}"},{"utterance":"Book a hotel"},{"utterance":"I want to book a hotel "}],"intentConfirmationSetting":{"isActive":true,"promptSpecification":{"messageGroupsList":[{"message":{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"That was a {NumberOfNights} nights stay in a {RoomType} room in {City} for {NumberOfGuests} guests. Checking in on {CheckInDate}. Is that correct?"},"imageResponseCard":null},"variations":null}],"maxRetries":4,"messageSelectionStrategy":"Random","allowInterrupt":true,"promptAttemptsSpecification":{"Retry2":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry3":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry1":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry4":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Initial":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true}}},"declinationResponse":{"messageGroupsList":[{"message":{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"Ok. Let’s try that again."},"imageResponseCard":null},"variations":null}],"allowInterrupt":true},"failureNextStep":{"sessionAttributes":{},"intent":{"name":"FallbackIntent","slots":{}},"dialogAction":{"type":"StartIntent","slotToElicit":null,"suppressNextMessage":null}},"elicitationCodeHook":{"enableCodeHookInvocation":true,"invocationLabel":null},"confirmationResponse":{"messageGroupsList":[{"message":{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"Thank you."},"imageResponseCard":null},"variations":null}],"allowInterrupt":true},"confirmationNextStep":{"sessionAttributes":{},"intent":{"name":null,"slots":{}},"dialogAction":{"type":"FulfillIntent","slotToElicit":null,"suppressNextMessage":null}},"declinationNextStep":{"sessionAttributes":{},"intent":{"name":null,"slots":{"Comment":{"value":{"interpretedValue":null},"values":null,"shape":null},"NumberOfGuests":{"value":{"interpretedValue":null},"values":null,"shape":null},"RoomType":{"value":{"interpretedValue":null},"values":null,"shape":null},"CheckInDate":{"value":{"interpretedValue":null},"values":null,"shape":null},"ProvideComment":{"value":{"interpretedValue":null},"values":null,"shape":null},"NumberOfNights":{"value":{"interpretedValue":null},"values":null,"shape":null},"City":{"value":{"interpretedValue":null},"values":null,"shape":null}}},"dialogAction":{"type":"ElicitSlot","slotToElicit":"City","suppressNextMessage":null}}},"intentClosingSetting":null,"initialResponseSetting":{"conditional":null,"codeHook":null,"nextStep":{"sessionAttributes":{},"intent":{"name":null,"slots":{}},"dialogAction":{"type":"ElicitSlot","slotToElicit":"City","suppressNextMessage":null}},"initialResponse":null},"inputContexts":null,"outputContexts":null,"kendraConfiguration":null,"qnAIntentConfiguration":null,"bedrockAgentIntentConfiguration":null,"dialogCodeHook":null,"fulfillmentCodeHook":{"isActive":true,"postFulfillmentStatusSpecification":{"failureResponse":null,"failureNextStep":{"sessionAttributes":{},"intent":{"name":"FallbackIntent","slots":{}},"dialogAction":{"type":"StartIntent","slotToElicit":null,"suppressNextMessage":null}},"successResponse":{"messageGroupsList":[{"message":{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"Your reservation has been processed successfully. Your booking number is: ABC123"},"imageResponseCard":null},"variations":null}],"allowInterrupt":true},"successNextStep":{"sessionAttributes":{},"intent":{"name":null,"slots":{}},"dialogAction":{"type":"EndConversation","slotToElicit":null,"suppressNextMessage":null}},"timeoutResponse":null,"timeoutNextStep":{"sessionAttributes":{},"intent":{"name":"FallbackIntent","slots":{}},"dialogAction":{"type":"StartIntent","slotToElicit":null,"suppressNextMessage":null}}},"fulfillmentUpdatesSpecification":null,"enabled":true},"slotPriorities":[{"priority":8,"slotName":"FirstName"},{"priority":9,"slotName":"LastName"},{"priority":4,"slotName":"RoomType"},{"priority":5,"slotName":"NumberOfGuests"},{"priority":6,"slotName":"ProvideComment"},{"priority":3,"slotName":"NumberOfNights"},{"priority":2,"slotName":"CheckInDate"},{"priority":1,"slotName":"City"},{"priority":7,"slotName":"Comment"}]} -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/BotLocales/en_US/Intents/BookHotel/Slots/CheckInDate/Slot.json: -------------------------------------------------------------------------------- 1 | {"name":"CheckInDate","identifier":"JIPOGHGS0B","description":null,"slotTypeName":"AMAZON.Date","obfuscationSetting":null,"valueElicitationSetting":{"slotCaptureSetting":{"codeHook":null,"captureResponse":null,"captureNextStep":{"sessionAttributes":{},"intent":{"name":null,"slots":{}},"dialogAction":{"type":"ElicitSlot","slotToElicit":"NumberOfNights","suppressNextMessage":null}},"captureConditional":null,"failureResponse":null,"failureNextStep":{"sessionAttributes":{},"intent":{"name":"FallbackIntent","slots":{}},"dialogAction":{"type":"StartIntent","slotToElicit":null,"suppressNextMessage":null}},"failureConditional":null,"elicitationCodeHook":{"enableCodeHookInvocation":true,"invocationLabel":null}},"slotConstraint":"Required","promptSpecification":{"messageGroupsList":[{"message":{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"What date will you be checking in?"},"imageResponseCard":null},"variations":[{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"When will you check in? You can say things like tomorrow, Next Wednesday or December 21st."},"imageResponseCard":null},{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"Please enter the date you want to check in using four-digit year, two-digit month and two-digit day. "},"imageResponseCard":null}]}],"maxRetries":3,"messageSelectionStrategy":"Ordered","allowInterrupt":true,"promptAttemptsSpecification":{"Retry2":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry3":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Initial":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry1":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true}}},"defaultValueSpecification":null,"sampleUtterances":null,"waitAndContinueSpecification":null,"slotResolutionSetting":{"slotResolutionStrategy":"EnhancedFallback"}},"multipleValuesSetting":null} -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/BotLocales/en_US/Intents/BookHotel/Slots/City/Slot.json: -------------------------------------------------------------------------------- 1 | {"name":"City","identifier":"TPJGF4HADJ","description":null,"slotTypeName":"AMAZON.City","obfuscationSetting":null,"valueElicitationSetting":{"slotCaptureSetting":{"codeHook":null,"captureResponse":null,"captureNextStep":{"sessionAttributes":{},"intent":{"name":null,"slots":{}},"dialogAction":{"type":"ElicitSlot","slotToElicit":"CheckInDate","suppressNextMessage":null}},"captureConditional":null,"failureResponse":null,"failureNextStep":{"sessionAttributes":{},"intent":{"name":"FallbackIntent","slots":{}},"dialogAction":{"type":"StartIntent","slotToElicit":null,"suppressNextMessage":null}},"failureConditional":null,"elicitationCodeHook":{"enableCodeHookInvocation":true,"invocationLabel":null}},"slotConstraint":"Required","promptSpecification":{"messageGroupsList":[{"message":{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"What city would you like to book the hotel in?"},"imageResponseCard":null},"variations":[{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"Where would you like to book the hotel?"},"imageResponseCard":null},{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"What city?"},"imageResponseCard":null}]}],"maxRetries":3,"messageSelectionStrategy":"Ordered","allowInterrupt":true,"promptAttemptsSpecification":{"Retry2":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry3":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Initial":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry1":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true}}},"defaultValueSpecification":null,"sampleUtterances":null,"waitAndContinueSpecification":null,"slotResolutionSetting":{"slotResolutionStrategy":"EnhancedFallback"}},"multipleValuesSetting":null} -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/BotLocales/en_US/Intents/BookHotel/Slots/Comment/Slot.json: -------------------------------------------------------------------------------- 1 | {"name":"Comment","identifier":"XSEVLYK07S","description":null,"slotTypeName":"AMAZON.FreeFormInput","obfuscationSetting":null,"valueElicitationSetting":{"slotCaptureSetting":{"codeHook":null,"captureResponse":{"messageGroupsList":[{"message":{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"Ok. I have added a comment to your reservation: {Comment}"},"imageResponseCard":null},"variations":null}],"allowInterrupt":true},"captureNextStep":{"sessionAttributes":null,"intent":{"name":null,"slots":{}},"dialogAction":{"type":"ElicitSlot","slotToElicit":"FirstName","suppressNextMessage":null}},"captureConditional":null,"failureResponse":null,"failureNextStep":{"sessionAttributes":{},"intent":{"name":"FallbackIntent","slots":{}},"dialogAction":{"type":"StartIntent","slotToElicit":null,"suppressNextMessage":null}},"failureConditional":null,"elicitationCodeHook":{"enableCodeHookInvocation":true,"invocationLabel":null}},"slotConstraint":"Required","promptSpecification":{"messageGroupsList":[{"message":{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"What comment or request do you have?"},"imageResponseCard":null},"variations":[{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"What would you like to request of the hotel?"},"imageResponseCard":null},{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"Please tell me the requeest or message you would like to add to your reservation."},"imageResponseCard":null}]}],"maxRetries":4,"messageSelectionStrategy":"Ordered","allowInterrupt":true,"promptAttemptsSpecification":{"Retry2":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry4":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry3":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Initial":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry1":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true}}},"defaultValueSpecification":null,"sampleUtterances":null,"waitAndContinueSpecification":null},"multipleValuesSetting":null} -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/BotLocales/en_US/Intents/BookHotel/Slots/FirstName/Slot.json: -------------------------------------------------------------------------------- 1 | {"name":"FirstName","identifier":"0WDI9WEMWW","description":null,"slotTypeName":"AMAZON.FirstName","obfuscationSetting":null,"valueElicitationSetting":{"slotCaptureSetting":{"codeHook":null,"captureResponse":null,"captureNextStep":{"sessionAttributes":null,"intent":{"name":null,"slots":null},"dialogAction":{"type":"ElicitSlot","slotToElicit":"LastName","suppressNextMessage":null}},"captureConditional":null,"failureResponse":null,"failureNextStep":{"sessionAttributes":null,"intent":{"name":"FallbackIntent","slots":null},"dialogAction":{"type":"StartIntent","slotToElicit":null,"suppressNextMessage":null}},"failureConditional":null,"elicitationCodeHook":{"enableCodeHookInvocation":true,"invocationLabel":null}},"slotConstraint":"Required","promptSpecification":{"messageGroupsList":[{"message":{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"First name"},"imageResponseCard":null},"variations":null}],"maxRetries":4,"messageSelectionStrategy":"Random","allowInterrupt":true,"promptAttemptsSpecification":{"Retry2":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry4":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry3":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Initial":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry1":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true}}},"defaultValueSpecification":null,"sampleUtterances":null,"waitAndContinueSpecification":null},"multipleValuesSetting":null} -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/BotLocales/en_US/Intents/BookHotel/Slots/LastName/Slot.json: -------------------------------------------------------------------------------- 1 | {"name":"LastName","identifier":"5C9UMKJ1KM","description":null,"slotTypeName":"AMAZON.LastName","obfuscationSetting":null,"valueElicitationSetting":{"slotCaptureSetting":{"codeHook":null,"captureResponse":null,"captureNextStep":{"sessionAttributes":null,"intent":{"name":null,"slots":null},"dialogAction":{"type":"ConfirmIntent","slotToElicit":null,"suppressNextMessage":null}},"captureConditional":null,"failureResponse":null,"failureNextStep":{"sessionAttributes":null,"intent":{"name":"FallbackIntent","slots":null},"dialogAction":{"type":"StartIntent","slotToElicit":null,"suppressNextMessage":null}},"failureConditional":null,"elicitationCodeHook":{"enableCodeHookInvocation":true,"invocationLabel":null}},"slotConstraint":"Required","promptSpecification":{"messageGroupsList":[{"message":{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"Last name"},"imageResponseCard":null},"variations":null}],"maxRetries":4,"messageSelectionStrategy":"Random","allowInterrupt":true,"promptAttemptsSpecification":{"Retry2":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry4":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry3":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Initial":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry1":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true}}},"defaultValueSpecification":null,"sampleUtterances":null,"waitAndContinueSpecification":null},"multipleValuesSetting":null} -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/BotLocales/en_US/Intents/BookHotel/Slots/NumberOfGuests/Slot.json: -------------------------------------------------------------------------------- 1 | {"name":"NumberOfGuests","identifier":"B4VNCQUTZB","description":null,"slotTypeName":"AMAZON.Number","obfuscationSetting":null,"valueElicitationSetting":{"slotCaptureSetting":{"codeHook":null,"captureResponse":null,"captureNextStep":{"sessionAttributes":{},"intent":{"name":null,"slots":{}},"dialogAction":{"type":"ElicitSlot","slotToElicit":"ProvideComment","suppressNextMessage":null}},"captureConditional":null,"failureResponse":null,"failureNextStep":{"sessionAttributes":{},"intent":{"name":"FallbackIntent","slots":{}},"dialogAction":{"type":"StartIntent","slotToElicit":null,"suppressNextMessage":null}},"failureConditional":null,"elicitationCodeHook":{"enableCodeHookInvocation":true,"invocationLabel":null}},"slotConstraint":"Required","promptSpecification":{"messageGroupsList":[{"message":{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"How many guests?"},"imageResponseCard":null},"variations":[{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"How many guests is the reservation for?"},"imageResponseCard":null},{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"How many guests will be staying in the room?"},"imageResponseCard":null}]}],"maxRetries":3,"messageSelectionStrategy":"Ordered","allowInterrupt":true,"promptAttemptsSpecification":{"Retry2":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry3":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Initial":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry1":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true}}},"defaultValueSpecification":null,"sampleUtterances":null,"waitAndContinueSpecification":null,"slotResolutionSetting":{"slotResolutionStrategy":"EnhancedFallback"}},"multipleValuesSetting":null} -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/BotLocales/en_US/Intents/BookHotel/Slots/NumberOfNights/Slot.json: -------------------------------------------------------------------------------- 1 | {"name":"NumberOfNights","identifier":"ICVZXL4KJW","description":null,"slotTypeName":"AMAZON.Number","obfuscationSetting":null,"valueElicitationSetting":{"slotCaptureSetting":{"codeHook":null,"captureResponse":null,"captureNextStep":{"sessionAttributes":{},"intent":{"name":null,"slots":{}},"dialogAction":{"type":"ElicitSlot","slotToElicit":"RoomType","suppressNextMessage":null}},"captureConditional":null,"failureResponse":null,"failureNextStep":{"sessionAttributes":{},"intent":{"name":"FallbackIntent","slots":{}},"dialogAction":{"type":"StartIntent","slotToElicit":null,"suppressNextMessage":null}},"failureConditional":null,"elicitationCodeHook":{"enableCodeHookInvocation":true,"invocationLabel":null}},"slotConstraint":"Required","promptSpecification":{"messageGroupsList":[{"message":{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"For how many nights?"},"imageResponseCard":null},"variations":[{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"How many nights will you be staying?"},"imageResponseCard":null},{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"How many nights should the reservation be for?"},"imageResponseCard":null}]}],"maxRetries":3,"messageSelectionStrategy":"Ordered","allowInterrupt":true,"promptAttemptsSpecification":{"Retry2":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry3":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Initial":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry1":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true}}},"defaultValueSpecification":null,"sampleUtterances":null,"waitAndContinueSpecification":null,"slotResolutionSetting":{"slotResolutionStrategy":"EnhancedFallback"}},"multipleValuesSetting":null} -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/BotLocales/en_US/Intents/BookHotel/Slots/ProvideComment/Slot.json: -------------------------------------------------------------------------------- 1 | {"name":"ProvideComment","identifier":"CCEU70138X","description":null,"slotTypeName":"AMAZON.Confirmation","obfuscationSetting":null,"valueElicitationSetting":{"slotCaptureSetting":{"codeHook":null,"captureResponse":null,"captureNextStep":{"sessionAttributes":{},"intent":{"name":null,"slots":{}},"dialogAction":{"type":"EvaluateConditional","slotToElicit":null,"suppressNextMessage":null}},"captureConditional":{"isActive":true,"conditionalBranches":[{"name":"Yes","response":null,"condition":{"expressionString":"{ProvideComment} = \"Yes\""},"nextStep":{"sessionAttributes":{},"intent":{"name":null,"slots":{}},"dialogAction":{"type":"ElicitSlot","slotToElicit":"Comment","suppressNextMessage":null}}}],"defaultBranch":{"response":null,"nextStep":{"sessionAttributes":{},"intent":{"name":null,"slots":{}},"dialogAction":{"type":"ConfirmIntent","slotToElicit":null,"suppressNextMessage":null}}}},"failureResponse":null,"failureNextStep":{"sessionAttributes":{},"intent":{"name":"FallbackIntent","slots":{}},"dialogAction":{"type":"StartIntent","slotToElicit":null,"suppressNextMessage":null}},"failureConditional":null,"elicitationCodeHook":{"enableCodeHookInvocation":true,"invocationLabel":null}},"slotConstraint":"Required","promptSpecification":{"messageGroupsList":[{"message":{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"Do you have any request or comments you want to provide for the hotel?"},"imageResponseCard":null},"variations":[{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"Do you have any requests or comments for the hotel? Please say yes or no."},"imageResponseCard":null},{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"If you have a request, for example,an early check-in, say yes. Otherwise say no."},"imageResponseCard":null}]}],"maxRetries":4,"messageSelectionStrategy":"Ordered","allowInterrupt":true,"promptAttemptsSpecification":{"Retry2":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry4":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry3":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Initial":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry1":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true}}},"defaultValueSpecification":null,"sampleUtterances":null,"waitAndContinueSpecification":null,"slotResolutionSetting":{"slotResolutionStrategy":"EnhancedFallback"}},"multipleValuesSetting":null} -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/BotLocales/en_US/Intents/BookHotel/Slots/RoomType/Slot.json: -------------------------------------------------------------------------------- 1 | {"name":"RoomType","identifier":"ALKJT7XQPP","description":null,"slotTypeName":"RoomTypeValues","obfuscationSetting":null,"valueElicitationSetting":{"slotCaptureSetting":{"codeHook":null,"captureResponse":null,"captureNextStep":{"sessionAttributes":{},"intent":{"name":null,"slots":{}},"dialogAction":{"type":"ElicitSlot","slotToElicit":"NumberOfGuests","suppressNextMessage":null}},"captureConditional":null,"failureResponse":null,"failureNextStep":{"sessionAttributes":{},"intent":{"name":"FallbackIntent","slots":{}},"dialogAction":{"type":"StartIntent","slotToElicit":null,"suppressNextMessage":null}},"failureConditional":null,"elicitationCodeHook":{"enableCodeHookInvocation":true,"invocationLabel":null}},"slotConstraint":"Required","promptSpecification":{"messageGroupsList":[{"message":{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"What kind of room would you like?"},"imageResponseCard":null},"variations":[{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"How many guests is the reservation for?"},"imageResponseCard":null},{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"How many guests will be staying in the room?"},"imageResponseCard":null}]}],"maxRetries":3,"messageSelectionStrategy":"Ordered","allowInterrupt":true,"promptAttemptsSpecification":{"Retry2":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry3":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Initial":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry1":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true}}},"defaultValueSpecification":null,"sampleUtterances":null,"waitAndContinueSpecification":null},"multipleValuesSetting":null} -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/BotLocales/en_US/Intents/CancelReservation/Intent.json: -------------------------------------------------------------------------------- 1 | {"name":"CancelReservation","identifier":"PUYQXG2XWC","description":null,"parentIntentSignature":null,"sampleUtterances":[{"utterance":"I want to cancel my reservation"},{"utterance":"Please cancel reservation {ConfirmationNumber}"},{"utterance":"Cancel reservation number {ConfirmationNumber}"},{"utterance":"Could you cancel reservation {ConfirmationNumber} for me"},{"utterance":"I need to cancel reservation with confirmation number {ConfirmationNumber}"},{"utterance":"Cancel my reservation with confirmation {ConfirmationNumber}"},{"utterance":"I would like to cancel reservation"},{"utterance":"Cancel my reservation please"},{"utterance":"I want to cancel reservation"},{"utterance":"Cancel reservation"}],"intentConfirmationSetting":null,"intentClosingSetting":null,"initialResponseSetting":{"conditional":null,"codeHook":{"isActive":true,"enableCodeHookInvocation":true,"invocationLabel":null,"postCodeHookSpecification":{"failureResponse":null,"failureNextStep":{"sessionAttributes":null,"intent":null,"dialogAction":{"type":"EndConversation","slotToElicit":null,"suppressNextMessage":null}},"failureConditional":null,"successResponse":null,"successNextStep":{"sessionAttributes":null,"intent":null,"dialogAction":{"type":"ElicitSlot","slotToElicit":"ConfirmationNumber","suppressNextMessage":null}},"successConditional":null,"timeoutResponse":null,"timeoutNextStep":{"sessionAttributes":null,"intent":null,"dialogAction":{"type":"EndConversation","slotToElicit":null,"suppressNextMessage":null}},"timeoutConditional":null}},"nextStep":{"sessionAttributes":null,"intent":null,"dialogAction":{"type":"InvokeDialogCodeHook","slotToElicit":null,"suppressNextMessage":null}},"initialResponse":null},"inputContexts":null,"outputContexts":null,"kendraConfiguration":null,"qnAIntentConfiguration":null,"bedrockAgentIntentConfiguration":null,"dialogCodeHook":null,"fulfillmentCodeHook":null,"slotPriorities":[{"priority":1,"slotName":"ConfirmationNumber"}]} -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/BotLocales/en_US/Intents/CancelReservation/Slots/ConfirmationNumber/Slot.json: -------------------------------------------------------------------------------- 1 | {"name":"ConfirmationNumber","identifier":"ACDWHNL9PR","description":null,"slotTypeName":"AMAZON.AlphaNumeric","obfuscationSetting":null,"valueElicitationSetting":{"slotCaptureSetting":{"codeHook":null,"captureResponse":null,"captureNextStep":{"sessionAttributes":null,"intent":null,"dialogAction":{"type":"EndConversation","slotToElicit":null,"suppressNextMessage":null}},"captureConditional":null,"failureResponse":null,"failureNextStep":{"sessionAttributes":null,"intent":{"name":"FallbackIntent","slots":null},"dialogAction":{"type":"StartIntent","slotToElicit":null,"suppressNextMessage":null}},"failureConditional":null,"elicitationCodeHook":{"enableCodeHookInvocation":true,"invocationLabel":null}},"slotConstraint":"Required","promptSpecification":{"messageGroupsList":[{"message":{"ssmlMessage":null,"customPayload":null,"plainTextMessage":{"value":"Can you give the ConfirmationNumber?"},"imageResponseCard":null},"variations":null}],"maxRetries":3,"messageSelectionStrategy":"Random","allowInterrupt":true,"promptAttemptsSpecification":{"Retry2":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry3":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Initial":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry1":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true}}},"defaultValueSpecification":null,"sampleUtterances":null,"waitAndContinueSpecification":null},"multipleValuesSetting":null} -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/BotLocales/en_US/Intents/FallbackIntent/Intent.json: -------------------------------------------------------------------------------- 1 | {"name":"FallbackIntent","identifier":"FALLBCKINT","description":"Default intent when no other intent matches","parentIntentSignature":"AMAZON.FallbackIntent","sampleUtterances":null,"intentConfirmationSetting":null,"intentClosingSetting":null,"initialResponseSetting":{"conditional":null,"codeHook":{"isActive":true,"enableCodeHookInvocation":true,"invocationLabel":null,"postCodeHookSpecification":{"failureResponse":null,"failureNextStep":{"sessionAttributes":null,"intent":null,"dialogAction":{"type":"EndConversation","slotToElicit":null,"suppressNextMessage":null}},"failureConditional":null,"successResponse":null,"successNextStep":{"sessionAttributes":null,"intent":null,"dialogAction":{"type":"EndConversation","slotToElicit":null,"suppressNextMessage":null}},"successConditional":null,"timeoutResponse":null,"timeoutNextStep":{"sessionAttributes":null,"intent":null,"dialogAction":{"type":"EndConversation","slotToElicit":null,"suppressNextMessage":null}},"timeoutConditional":null}},"nextStep":{"sessionAttributes":null,"intent":null,"dialogAction":{"type":"InvokeDialogCodeHook","slotToElicit":null,"suppressNextMessage":null}},"initialResponse":null},"inputContexts":null,"outputContexts":null,"kendraConfiguration":null,"qnAIntentConfiguration":null,"bedrockAgentIntentConfiguration":null,"dialogCodeHook":null,"fulfillmentCodeHook":null,"slotPriorities":[]} -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/BotLocales/en_US/Intents/Welcome/ConversationFlow.json: -------------------------------------------------------------------------------- 1 | {"intentName":"Welcome","identifier":"CONVFLOWID","conversationFlowData":{"metadata":{"schemaVersion":"1","dataFormat":"JSON"},"blocks":[{"blockType":"StartIntent","dataLocations":["intent/StartIntent_"],"blockId":"startintent","coordinate":{"x":"200","y":"400"}},{"blockType":"GetSlotValue","dataLocations":["intent/GetSlotValue-option_"],"blockId":"getslotvalue_option","coordinate":{"x":"549","y":"403"}},{"blockType":"Fulfillment","dataLocations":["intent/Fulfillment_"],"blockId":"fulfillment","coordinate":{"x":"895","y":"483"}},{"blockType":"End","dataLocations":["intent/GetSlotValue-option_/End_GetSlotValueFailure","intent/Fulfillment_/End_FulfillmentError","intent/Fulfillment_/End_FulfillmentTimeout"],"blockId":"end","coordinate":{"x":"963","y":"1047"}},{"blockType":"Condition","dataLocations":["intent/Fulfillment_/Condition_FulfillmentSuccess"],"blockId":"dm-node-0230f8fb-57ae-465c-be7f-84742ad9af05","coordinate":{"x":"1226","y":"557"}},{"blockType":"GoToIntent","dataLocations":["intent/Fulfillment_/Condition_FulfillmentSuccess/GoToIntent-QnA_ns_DefaultBranch"],"blockId":"gotointent_QnA_ns","coordinate":{"x":"1823","y":"400"}},{"blockType":"GoToIntent","dataLocations":["intent/Fulfillment_/Condition_FulfillmentSuccess/GoToIntent-_ConditionTwo"],"blockId":"dm-node-0cb3a236-fd7a-4452-a9e6-41d2d68215b3","coordinate":{"x":"1860","y":"976"}},{"blockType":"GoToIntent","dataLocations":["intent/Fulfillment_/Condition_FulfillmentSuccess/GoToIntent-_ConditionOne"],"blockId":"dm-node-ad2b921e-29ed-468c-9802-a0a8880074d7","coordinate":{"x":"1868","y":"708"}},{"blockType":"GoToIntent","dataLocations":[],"blockId":"gotointent_BookHotel_ns","coordinate":{"x":"1825","y":"400"}},{"blockType":"GoToIntent","dataLocations":[],"blockId":"gotointent_CancelReservation_ns","coordinate":{"x":"1825","y":"400"}}],"edges":[{"vertices":[{"x":"804","y":"618"},{"x":"874","y":"618"},{"x":"944","y":"618"},{"x":"1014","y":"618"},{"x":"1014","y":"688"},{"x":"1014","y":"758"},{"x":"1014","y":"828"},{"x":"1014","y":"898"},{"x":"1014","y":"968"},{"x":"1014","y":"1038"},{"x":"1014","y":"1064"},{"x":"948","y":"1064"}],"edgeLocation":"intent/GetSlotValue-option_/End_GetSlotValueFailure","originBlockId":"getslotvalue_option","destinationBlockId":"end","originBlockPort":"GetSlotValueFailure","destinationBlockPort":"EndConversationInput"},{"vertices":[{"x":"1471","y":"667"},{"x":"1541","y":"667"},{"x":"1611","y":"667"},{"x":"1681","y":"667"},{"x":"1751","y":"667"},{"x":"1751","y":"597"},{"x":"1751","y":"527"},{"x":"1751","y":"457"},{"x":"1751","y":"417"},{"x":"1808","y":"417"}],"edgeLocation":"intent/Fulfillment_/Condition_FulfillmentSuccess/GoToIntent-QnA_ns_DefaultBranch","originBlockId":"dm-node-0230f8fb-57ae-465c-be7f-84742ad9af05","destinationBlockId":"gotointent_QnA_ns","originBlockPort":"DefaultBranch","destinationBlockPort":"GoToIntentInput"},{"vertices":[{"x":"1150","y":"643"},{"x":"1150","y":"574"},{"x":"1211","y":"574"}],"edgeLocation":"intent/Fulfillment_/Condition_FulfillmentSuccess","originBlockId":"fulfillment","destinationBlockId":"dm-node-0230f8fb-57ae-465c-be7f-84742ad9af05","originBlockPort":"FulfillmentSuccess","destinationBlockPort":"ConditionInput"},{"vertices":[{"x":"1150","y":"683"},{"x":"1150","y":"753"},{"x":"1150","y":"823"},{"x":"1150","y":"893"},{"x":"1150","y":"963"},{"x":"1150","y":"1033"},{"x":"1080","y":"1033"},{"x":"1010","y":"1033"},{"x":"1010","y":"1064"},{"x":"948","y":"1064"}],"edgeLocation":"intent/Fulfillment_/End_FulfillmentError","originBlockId":"fulfillment","destinationBlockId":"end","originBlockPort":"FulfillmentError","destinationBlockPort":"EndConversationInput"},{"vertices":[{"x":"1150","y":"723"},{"x":"1150","y":"793"},{"x":"1150","y":"863"},{"x":"1150","y":"933"},{"x":"1150","y":"1003"},{"x":"1080","y":"1003"},{"x":"1010","y":"1003"},{"x":"1010","y":"1064"},{"x":"948","y":"1064"}],"edgeLocation":"intent/Fulfillment_/End_FulfillmentTimeout","originBlockId":"fulfillment","destinationBlockId":"end","originBlockPort":"FulfillmentTimeout","destinationBlockPort":"EndConversationInput"},{"vertices":[{"x":"1471","y":"859"},{"x":"1541","y":"859"},{"x":"1611","y":"859"},{"x":"1681","y":"859"},{"x":"1751","y":"859"},{"x":"1821","y":"859"},{"x":"1821","y":"929"},{"x":"1821","y":"993"},{"x":"1845","y":"993"}],"edgeLocation":"intent/Fulfillment_/Condition_FulfillmentSuccess/GoToIntent-_ConditionTwo","originBlockId":"dm-node-0230f8fb-57ae-465c-be7f-84742ad9af05","destinationBlockId":"dm-node-0cb3a236-fd7a-4452-a9e6-41d2d68215b3","originBlockPort":"ConditionTwo","destinationBlockPort":"GoToIntentInput"},{"vertices":[{"x":"1471","y":"763"},{"x":"1541","y":"763"},{"x":"1611","y":"763"},{"x":"1681","y":"763"},{"x":"1751","y":"763"},{"x":"1821","y":"763"},{"x":"1821","y":"725"},{"x":"1853","y":"725"}],"edgeLocation":"intent/Fulfillment_/Condition_FulfillmentSuccess/GoToIntent-_ConditionOne","originBlockId":"dm-node-0230f8fb-57ae-465c-be7f-84742ad9af05","destinationBlockId":"dm-node-ad2b921e-29ed-468c-9802-a0a8880074d7","originBlockPort":"ConditionOne","destinationBlockPort":"GoToIntentInput"}]}} -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/BotLocales/en_US/Intents/Welcome/Intent.json: -------------------------------------------------------------------------------- 1 | {"name":"Welcome","identifier":"KJBYJNAE4U","description":null,"parentIntentSignature":null,"sampleUtterances":[{"utterance":"hello"},{"utterance":"good day"},{"utterance":"greetings"},{"utterance":"how are you"},{"utterance":"nice to meet you"},{"utterance":"Hi"}],"intentConfirmationSetting":null,"intentClosingSetting":null,"initialResponseSetting":{"conditional":null,"codeHook":null,"nextStep":{"sessionAttributes":{},"intent":{"name":null,"slots":{}},"dialogAction":{"type":"ElicitSlot","slotToElicit":"option","suppressNextMessage":null}},"initialResponse":null},"inputContexts":null,"outputContexts":null,"kendraConfiguration":null,"qnAIntentConfiguration":null,"bedrockAgentIntentConfiguration":null,"dialogCodeHook":{"enabled":false},"fulfillmentCodeHook":{"isActive":true,"postFulfillmentStatusSpecification":{"failureResponse":null,"failureNextStep":{"sessionAttributes":{},"intent":{"name":null,"slots":{}},"dialogAction":{"type":"EndConversation","slotToElicit":null,"suppressNextMessage":null}},"successResponse":null,"successNextStep":{"sessionAttributes":{},"intent":{"name":null,"slots":{}},"dialogAction":{"type":"EvaluateConditional","slotToElicit":null,"suppressNextMessage":null}},"successConditional":{"isActive":true,"conditionalBranches":[{"name":"BookHotel","response":null,"condition":{"expressionString":"{option} = \"book hotel\""},"nextStep":{"sessionAttributes":{},"intent":{"name":"BookHotel","slots":{}},"dialogAction":{"type":"StartIntent","slotToElicit":null,"suppressNextMessage":null}}},{"name":"Cancel","response":null,"condition":{"expressionString":"{option} = \"cancel reservation\""},"nextStep":{"sessionAttributes":{},"intent":{"name":"CancelReservation","slots":{}},"dialogAction":{"type":"StartIntent","slotToElicit":null,"suppressNextMessage":null}}}],"defaultBranch":{"response":null,"nextStep":{"sessionAttributes":{},"intent":{"name":"QnA","slots":{}},"dialogAction":{"type":"StartIntent","slotToElicit":null,"suppressNextMessage":null}}}},"timeoutResponse":null,"timeoutNextStep":{"sessionAttributes":{},"intent":{"name":null,"slots":{}},"dialogAction":{"type":"EndConversation","slotToElicit":null,"suppressNextMessage":null}}},"fulfillmentUpdatesSpecification":null,"enabled":false},"slotPriorities":[{"priority":0,"slotName":"option"}]} -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/BotLocales/en_US/Intents/Welcome/Slots/option/Slot.json: -------------------------------------------------------------------------------- 1 | {"name":"option","identifier":"8EWT9HA0JE","description":null,"slotTypeName":"AMAZON.FreeFormInput","obfuscationSetting":null,"valueElicitationSetting":{"slotCaptureSetting":{"codeHook":null,"captureResponse":null,"captureNextStep":{"sessionAttributes":{},"intent":{"name":null,"slots":{}},"dialogAction":{"type":"FulfillIntent","slotToElicit":null,"suppressNextMessage":null}},"captureConditional":null,"failureResponse":null,"failureNextStep":{"sessionAttributes":{},"intent":{"name":null,"slots":{}},"dialogAction":{"type":"EndConversation","slotToElicit":null,"suppressNextMessage":null}},"failureConditional":null,"elicitationCodeHook":{"enableCodeHookInvocation":false,"invocationLabel":null}},"slotConstraint":"Required","promptSpecification":{"messageGroupsList":[{"message":{"ssmlMessage":null,"customPayload":null,"plainTextMessage":null,"imageResponseCard":{"title":"Hotel Genie - powered by Amazon Lex and Amazon Bedrock","subtitle":"Please select an option to proceed","imageUrl":null,"buttonsList":[{"value":"ask a question","text":"Ask a question"},{"value":"book hotel","text":"Book a hotel"},{"value":"cancel reservation","text":"Cancel reservation"}]}},"variations":null}],"maxRetries":4,"messageSelectionStrategy":"Random","allowInterrupt":true,"promptAttemptsSpecification":{"Retry2":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry4":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry3":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Initial":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true},"Retry1":{"textInputSpecification":{"startTimeoutMs":30000},"allowedInputTypes":{"allowAudioInput":true,"allowDTMFInput":true},"audioAndDTMFInputSpecification":{"audioSpecification":{"endTimeoutMs":640,"maxLengthMs":15000},"startTimeoutMs":4000,"dtmfSpecification":{"maxLength":513,"endTimeoutMs":5000,"deletionCharacter":"*","endCharacter":"#"}},"allowInterrupt":true}}},"defaultValueSpecification":null,"sampleUtterances":null,"waitAndContinueSpecification":null},"multipleValuesSetting":null} -------------------------------------------------------------------------------- /lex-srcs/GenAIHotelBookingLexChatbot/BotLocales/en_US/SlotTypes/RoomTypeValues/SlotType.json: -------------------------------------------------------------------------------- 1 | {"name":"RoomTypeValues","identifier":"SKDRINOLW4","description":null,"slotTypeValues":[{"synonyms":null,"sampleValue":{"value":"king"}},{"synonyms":null,"sampleValue":{"value":"queen"}},{"synonyms":[{"value":"two beds"}],"sampleValue":{"value":"two queen beds"}}],"parentSlotTypeSignature":null,"valueSelectionSetting":{"resolutionStrategy":"TOP_RESOLUTION","regexFilter":null}} -------------------------------------------------------------------------------- /lex-srcs/Manifest.json: -------------------------------------------------------------------------------- 1 | {"metaData":{"schemaVersion":"1","fileFormat":"LexJson","resourceType":"BOT"}} 2 | -------------------------------------------------------------------------------- /localTestEnvSetup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -xv 3 | # EDIT following paramters 4 | export STACK_ID=EDIT_ME 5 | export AWS_ACCOUNT_ID=EDIT_ME 6 | export AWS_DEFAULT_REGION=us-west-2 # EDIT_ME 7 | 8 | export GEN_AI_ECS_CLUSTER_PREFIX=GenAISamplesECSCluster 9 | export GEN_AI_ECS_SERVICE_PREFIX=GenAISamplesECSService 10 | export SUFFIX_ID=`echo $STACK_ID | cut -d '/' -f 3 | cut -d '-' -f 4 ` 11 | 12 | export TASK_DEFINITION=`aws ecs list-task-definitions --family-prefix "GenAISamplesTask-${SUFFIX_ID}" | jq -r '.taskDefinitionArns[0]'` 13 | 14 | aws ecs describe-task-definition --task-definition $TASK_DEFINITION --region ${AWS_DEFAULT_REGION} | jq '.taskDefinition.containerDefinitions[0].environment' > task_defn_env.json 15 | cat task_defn_env.json | jq -r '.[]' | jq '"export \(.name)=\(.value)"' | sed -e 's/^"//;s/=/="/g' > localTestEnv.sh 16 | 17 | echo "Setup AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY env variable values from SecretsManager for the matching secret name /env/genai/-GenAiDemoUser*" 18 | echo "Then source the localTestEnv.sh script to setup various env variables" 19 | 20 | echo "Then run streamlit using python v3.9 " 21 | echo "Streamlit command: streamlit run App.py --logger.level info --browser.gatherUsageStats false --browser.serverAddress 0.0.0.0 --server.enableCORS false --server.enableXsrfProtection false --server.enableXsrfProtection false --server.port 8080 " 22 | -------------------------------------------------------------------------------- /pages/GenAI_Agile_Guru.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT No Attribution 3 | 4 | Copyright 2023 Amazon Web Services 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 7 | software and associated documentation files (the "Software"), to deal in the Software 8 | without restriction, including without limitation the rights to use, copy, modify, 9 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 14 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 15 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 16 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 17 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | """ 19 | 20 | import boto3 21 | import streamlit as st 22 | import os 23 | from utils import gen_ai_selector 24 | from utils import cognito_helper 25 | 26 | import pages.imports.sts_assume_role as boto3_session 27 | 28 | 29 | autorefresh_session = boto3_session.run_autorefresh_session() 30 | s3 = autorefresh_session.client('s3') 31 | comprehend = autorefresh_session.client('comprehend') 32 | 33 | 34 | if 'user_stories' not in st.session_state: 35 | st.session_state['user_stories'] = None 36 | if 'data_model' not in st.session_state: 37 | st.session_state['data_model'] = None 38 | if 'api_specs' not in st.session_state: 39 | st.session_state['api_specs'] = None 40 | 41 | 42 | # Get environment variables 43 | bucket = os.environ['bucket'] 44 | languages = ['English', 'Spanish', 'German', 'Portugese', 'Irish', 'Star Trek - Klingon', 'Star Trek - Ferengi', 'Italian', 'French', 'Japanese', 'Mandarin', 'Tamil', 'Hindi', 'Telugu', 'Kannada', 'Arabic', 'Hebrew'] 45 | 46 | st.set_page_config(page_title="GenAI Agile Guru", page_icon="high_brightness") 47 | 48 | 49 | if 'stage' not in st.session_state: 50 | st.session_state.stage = 1 51 | if 'login_form_rendered' not in st.session_state: 52 | st.session_state.login_form_rendered = False 53 | if 'login_form_rendered_page' not in st.session_state: 54 | st.session_state.login_form_rendered_page = '' 55 | 56 | cognito_helper.manage_session() 57 | 58 | if not st.session_state["authenticated"]: 59 | cognito_helper.login() 60 | st.stop() 61 | 62 | 63 | 64 | st.markdown( 65 | """ 66 | ### :red[Note] 67 | - These demos are for informational purposes only. 68 | - Use these selection of [samples for playing with the demos](https://github.com/aws-samples/gen-ai-samples/sample-artifacts). 69 | - The demos should not be considered as an actual prototype or working version of a proposed solution 70 | """) 71 | 72 | 73 | st.markdown("# From epic to Epic in seconds") 74 | st.sidebar.header("GenAI Agile Guru") 75 | 76 | genai_models = gen_ai_selector.genai_models 77 | default_model = gen_ai_selector.default_genai_model_index 78 | model = st.sidebar.selectbox('Select a FM', genai_models, index=default_model) 79 | 80 | models = gen_ai_selector.genai_model_functions 81 | 82 | 83 | 84 | def GetAnswers(query): 85 | us_answer = None 86 | func = models[model]['func'] 87 | generated_text = func('Create 5 agile scrum user stories and acceptance criteria for each user story in '+language+' for '+ query.strip("query:")) 88 | if generated_text != '' and generated_text != None and 'Error' not in generated_text: 89 | generated_text = generated_text.replace("$","\$") 90 | us_answer = str(generated_text) 91 | else: 92 | us_answer = 'Sorry!! did not find an answer to your question, please try again' 93 | return us_answer 94 | 95 | st.write("**Instructions:** \n - Type an epic story \n - You will see user stories, data model, api specs, and BDD scenarios automatically generated for your epic \n") 96 | 97 | p_summary = ''' 98 | - funds transfer for banking \n 99 | - login to member portal and check balance \n 100 | - track and redeem rewards points \n 101 | - create customized landing page for website \n 102 | ''' 103 | 104 | st.sidebar.write('### Suggested epics to get started \n\n' + 105 | p_summary) 106 | 107 | input_text = st.text_input('**Type an epic**', key='text_ag') 108 | default_lang_ix = languages.index('English') 109 | language = st.selectbox( 110 | '**Select an output language.**', 111 | options=languages, index=default_lang_ix) 112 | generated_text = '' 113 | dm_generated_text = '' 114 | as_generated_text = '' 115 | bd_generated_text = '' 116 | us_answer = '' 117 | as_answer = '' 118 | dm_answer = '' 119 | bd_answer = '' 120 | func = models[model]['func'] 121 | 122 | if input_text != '': 123 | us_answer = GetAnswers(input_text) 124 | tab1, tab2, tab3, tab4 = st.tabs(["User Stories", "Data Model", "API Specs", "BDD Secenarios"]) 125 | #c1, c2 = st.columns(2) 126 | with tab1: 127 | if us_answer: 128 | st.write("**User stories for your epic**") 129 | st.write(us_answer) 130 | with tab2: 131 | dm_generated_text = func('Create a data model in '+language+' for each of the user stories in '+str(us_answer)) 132 | if dm_generated_text != '' and dm_generated_text != None and 'Error' not in dm_generated_text: 133 | #print('DM!!', dm_generated_text) 134 | dm_generated_text = dm_generated_text.replace("$","\$") 135 | dm_answer = str(dm_generated_text) 136 | st.session_state.data_model = dm_answer 137 | else: 138 | dm_answer = 'Sorry!! did not find an answer to your question, please try again' 139 | if dm_answer: 140 | st.write("**Data model for your user stories**") 141 | st.write(dm_answer) 142 | with tab3: 143 | as_generated_text = func('Create microservices API specifications in '+language+' for each of the data models in '+ str(dm_answer)) 144 | if as_generated_text != '' and as_generated_text != None and 'Error' not in as_generated_text: 145 | #print('AS!!', as_generated_text) 146 | as_generated_text = as_generated_text.replace("$","\$") 147 | as_answer = str(as_generated_text) 148 | st.session_state.api_specs = as_answer 149 | else: 150 | as_answer = 'Sorry!! did not find an answer to your question, please try again' 151 | if as_answer: 152 | st.write("**API Specs for your user stories**") 153 | st.write(as_answer) 154 | with tab4: 155 | bd_generated_text = func('Create behavior driven development scenarios using cucumber in '+language+' for each of the user stories in '+ str(us_answer)) 156 | if bd_generated_text != '' and bd_generated_text != None and 'Error' not in bd_generated_text: 157 | #print('BD!!', bd_generated_text) 158 | bd_generated_text = bd_generated_text.replace("$","\$") 159 | bd_answer = str(bd_generated_text) 160 | else: 161 | bd_answer = 'Sorry!! did not find an answer to your question, please try again' 162 | if bd_answer: 163 | st.write("**BDD Scenarios for your user stories**") 164 | st.write(bd_answer) 165 | 166 | st.sidebar.markdown('### :red[Cost of Bedrock Invocations] \n' 167 | + gen_ai_selector.report_cost()) 168 | -------------------------------------------------------------------------------- /pages/GenAI_ChatAway.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT No Attribution 3 | 4 | Copyright 2023 Amazon Web Services 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 7 | software and associated documentation files (the "Software"), to deal in the Software 8 | without restriction, including without limitation the rights to use, copy, modify, 9 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 14 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 15 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 16 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 17 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | """ 19 | import json 20 | import boto3 21 | import streamlit as st 22 | import datetime 23 | import uuid 24 | from streamlit_chat import message 25 | from boto3.dynamodb.conditions import Key 26 | import os 27 | from utils import gen_ai_selector 28 | from utils import cognito_helper 29 | 30 | import pages.imports.sts_assume_role as boto3_session 31 | 32 | 33 | autorefresh_session = boto3_session.run_autorefresh_session() 34 | comprehend = autorefresh_session.client('comprehend') 35 | bedrock = autorefresh_session.client('bedrock') 36 | 37 | # Get environment variables 38 | stack_id = os.environ.get('STACK_ID') 39 | st.set_page_config(page_title="GenAI Chat", page_icon="chat") 40 | 41 | # create a unique widget 42 | if 'key' not in st.session_state: 43 | st.session_state.key = str(uuid.uuid4()) 44 | 45 | 46 | if 'sessionID' not in st.session_state: 47 | st.session_state['sessionID'] = str(uuid.uuid4()) 48 | if 'prevText' not in st.session_state: 49 | st.session_state['prevText'] = None 50 | if 'count' not in st.session_state: 51 | st.session_state['count'] = 0 52 | if 'ca_chat_messages' not in st.session_state: 53 | st.session_state.ca_chat_messages = [{}] 54 | 55 | def get_old_chats(): 56 | return st.session_state.ca_chat_messages 57 | 58 | def store_chat(session, turn, question, answer): 59 | message_dict = {} 60 | message_dict['session'] = session 61 | message_dict['turn'] = turn 62 | message_dict['question'] = question 63 | message_dict['answer'] = answer 64 | st.session_state.ca_chat_messages.append(message_dict) 65 | 66 | if 'stage' not in st.session_state: 67 | st.session_state.stage = 1 68 | if 'login_form_rendered' not in st.session_state: 69 | st.session_state.login_form_rendered = False 70 | if 'login_form_rendered_page' not in st.session_state: 71 | st.session_state.login_form_rendered_page = '' 72 | 73 | cognito_helper.manage_session() 74 | 75 | if not st.session_state["authenticated"]: 76 | cognito_helper.login() 77 | st.stop() 78 | 79 | 80 | st.markdown( 81 | """ 82 | ### :red[Note] 83 | - These demos are for informational purposes only. 84 | - The demos should not be considered as an actual prototype or working version of a proposed solution 85 | """) 86 | 87 | st.sidebar.header("GenAI ChatAway") 88 | 89 | 90 | genai_models = gen_ai_selector.genai_models 91 | default_model = gen_ai_selector.default_genai_model_index 92 | model = st.sidebar.selectbox('Select a FM', genai_models, index=default_model) 93 | 94 | models = gen_ai_selector.genai_model_functions 95 | 96 | if 'Jumpstart' in model: 97 | st.markdown("# Chat with "+ model + ': ' + pref_jumpstart_model ) 98 | else: 99 | st.markdown("# Chat with "+ model) 100 | 101 | #model = 'Anthropic Claude' 102 | 103 | func = models[model]['func'] 104 | 105 | 106 | 107 | def GetAnswers(query): 108 | pii_list = [] 109 | sentiment = comprehend.detect_sentiment(Text=query, LanguageCode='en')['Sentiment'] 110 | lang = comprehend.detect_dominant_language(Text=query) 111 | lang_code = str(lang['Languages'][0]['LanguageCode']).split('-')[0] 112 | if lang_code in ['en']: 113 | resp_pii = comprehend.detect_pii_entities(Text=query, LanguageCode=lang_code) 114 | for pii in resp_pii['Entities']: 115 | if pii['Type'] not in ['NAME','URL','AGE','ADDRESS','DATE_TIME']: 116 | pii_list.append(pii['Type']) 117 | if len(pii_list) > 0: 118 | answer = "I am sorry but I found PII entities " + str(pii_list) + " in your query. Please remove PII entities and try again." 119 | return answer 120 | #query_type = '' 121 | #if "you" in query: 122 | # query_type = "BEING" 123 | 124 | if query == "cancel": 125 | answer = 'It was swell chatting with you. Goodbye for now' 126 | 127 | #elif query_type == "BEING": 128 | # answer = 'Kindly rephrase your question keeping it impersonal and try again.' 129 | 130 | else: 131 | func = models[model]['func'] 132 | answer = str(func(query)) 133 | return answer 134 | 135 | 136 | 137 | st.write("**Instructions:** \n - Type your query in the search bar \n - Only last five chats displayed for brevity \n") 138 | input_text = st.text_input('**Chat with me**', key='chat_text') 139 | p_summary = '' 140 | func = models[model]['func'] 141 | if input_text != '': 142 | message(input_text, is_user=True, key=str(uuid.uuid4())) 143 | 144 | if st.session_state.prevText is not None and len(st.session_state.prevText) > 1: 145 | result = GetAnswers('Answer from this text if the question is related to this text. Otherwise answer the question directly without referring to this text: '+str(st.session_state.prevText)+' ' + input_text) 146 | else: 147 | result = GetAnswers(input_text) 148 | 149 | 150 | if result: 151 | if '$' in result: 152 | result = result.replace("$","\$") 153 | st.session_state.prevText = result 154 | 155 | message(result, key=str(uuid.uuid4())) 156 | if int(st.session_state.count) <= 5: 157 | old_chats = get_old_chats() 158 | if old_chats: 159 | for chat in old_chats: 160 | if 'question' in chat: 161 | message(chat['question'], is_user=True, key=str(uuid.uuid4())) 162 | if 'answer' in chat: 163 | message(chat['answer'], key=str(uuid.uuid4())) 164 | else: 165 | st.session_state.count == 0 166 | 167 | st.session_state.count = int(st.session_state.count) + 1 168 | store_chat(st.session_state.sessionID, st.session_state.count, input_text, result) 169 | p_text = func('Generate three prompts to query the text: '+ result) 170 | p_text1 = [] 171 | p_text2 = '' 172 | if p_text is not None and p_text != '' and 'Error' not in p_text: 173 | p_text.replace("$","USD") 174 | p_text1 = p_text.split('\n') 175 | for i,t in enumerate(p_text1): 176 | if i > 1: 177 | p_text2 += t.split('\n')[0]+'\n\n' 178 | else: 179 | p_text2 += t + '\n\n' 180 | 181 | p_summary = p_text2 182 | st.sidebar.markdown('### Suggested prompts for further insights \n\n' + 183 | p_summary) 184 | 185 | st.sidebar.markdown('### :red[Cost of Bedrock Invocations] \n' 186 | + gen_ai_selector.report_cost()) 187 | -------------------------------------------------------------------------------- /pages/GenAI_enterprise_search_interpreter.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT No Attribution 3 | 4 | Copyright 2023 Amazon Web Services 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 7 | software and associated documentation files (the "Software"), to deal in the Software 8 | without restriction, including without limitation the rights to use, copy, modify, 9 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 14 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 15 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 16 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 17 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | """ 19 | import json 20 | import boto3 21 | import streamlit as st 22 | import datetime 23 | from io import BytesIO 24 | from PIL import Image 25 | import numpy as np 26 | import matplotlib.pyplot as plt 27 | import base64 28 | import uuid 29 | import ai21 30 | import string 31 | import anthropic 32 | import os 33 | 34 | from utils import gen_ai_selector 35 | from utils import cognito_helper 36 | 37 | import pages.imports.sts_assume_role as boto3_session 38 | 39 | 40 | autorefresh_session = boto3_session.run_autorefresh_session() 41 | comprehend = autorefresh_session.client('comprehend') 42 | bedrock = autorefresh_session.client('bedrock') 43 | kendra = autorefresh_session.client('kendra') 44 | 45 | # Get environment variables 46 | fsi_index_id = os.getenv('fsi_index_id', '') 47 | energy_index_id = os.getenv('energy_index_id', '') 48 | travel_index_id = os.getenv('travel_index_id', '') 49 | legal_index_id = os.getenv('legal_index_id', '') 50 | bucket = os.environ['bucket'] 51 | 52 | st.set_page_config(page_title="GenAI Enterprise Search and Interpreter", page_icon="mag_right") 53 | 54 | if 'stage' not in st.session_state: 55 | st.session_state.stage = 1 56 | if 'login_form_rendered' not in st.session_state: 57 | st.session_state.login_form_rendered = False 58 | if 'login_form_rendered_page' not in st.session_state: 59 | st.session_state.login_form_rendered_page = '' 60 | 61 | cognito_helper.manage_session() 62 | 63 | if not st.session_state["authenticated"]: 64 | cognito_helper.login() 65 | st.stop() 66 | 67 | 68 | 69 | st.markdown( 70 | """ 71 | ### :red[Note] 72 | - These demos are for informational purposes only. 73 | - Use these selection of [samples for playing with the demos](https://github.com/aws-samples/gen-ai-samples/sample-artifacts). 74 | - The demos should not be considered as an actual prototype or working version of a proposed solution 75 | """) 76 | 77 | 78 | 79 | st.markdown("# GenAI Enterprise Search") 80 | st.sidebar.header("GenAI search and interpret enterprise content") 81 | st.sidebar.markdown("### Make your pick") 82 | industry = '' 83 | industry = st.sidebar.selectbox( 84 | 'Select an industry', 85 | ('Financial Services', 'Energy', 'Legal', 'Travel and Transport')) 86 | 87 | if industry == 'Financial Services': 88 | st.sidebar.markdown(''' 89 | ### Example prompts you can try \n\n 90 | What is a company's EPS and what does it mean? \n 91 | Why are EU members not aligned on fiscal policy? \n 92 | ''') 93 | elif industry == 'Energy': 94 | st.sidebar.markdown(''' 95 | ### Example prompts you can try \n\n 96 | List the steps how oil is refined? \n 97 | What are the risks in hydrocarbon transport? \n 98 | ''') 99 | elif industry == 'Travel and Transport': 100 | st.sidebar.markdown(''' 101 | ### Example prompts you can try \n\n 102 | What is the maximum range for Airbus A330? \n 103 | What is the final approach speed for A350? \n 104 | ''') 105 | elif industry == 'Legal': 106 | st.sidebar.markdown(''' 107 | ### Example prompts you can try \n\n 108 | Who are the buyers and sellers mentioned in the contract? \n 109 | What is the closing date for the contract? \n 110 | What documents do the buyers need to approve? \n 111 | ''') 112 | model = 'Anthropic Claude' 113 | #model = st.sidebar.selectbox( 114 | # 'Select a LLM', 115 | # ('J2 Jumbo Instruct', 'Anthropic Claude')) 116 | 117 | 118 | 119 | genai_models = gen_ai_selector.genai_models 120 | default_model = gen_ai_selector.default_genai_model_index 121 | print('DEFAULT MODEL>...', default_model) 122 | model = st.sidebar.selectbox('Select a FM', genai_models, index=default_model) 123 | 124 | models = gen_ai_selector.genai_model_functions 125 | 126 | def call_Kendra(query_string, index_id): 127 | d = 0 128 | a = 0 129 | answer_text = '' 130 | document_text = '' 131 | result_set = [] 132 | result_dict = {} 133 | sources_list = [] 134 | result = ' ' 135 | 136 | if index_id is None or index_id == '': 137 | result_dict['snippet'] = ' ' 138 | result_dict['sources'] = ' ' 139 | return result_dict 140 | 141 | response = kendra.query( 142 | QueryText = query_string, 143 | IndexId = index_id) 144 | 145 | for query_result in response["ResultItems"]: 146 | entry = {} 147 | if query_result["Type"]=="ANSWER" or query_result["Type"]=="QUESTION_ANSWER": 148 | a += 1 149 | if a <= 1: 150 | answer_text = query_result["DocumentExcerpt"]["Text"] 151 | src = "Document: [Link]({})".format(query_result['DocumentAttributes'][0]['Value']['StringValue']) 152 | if len(query_result['DocumentAttributes']) > 1: 153 | src += " and Page: {}".format(query_result['DocumentAttributes'][1]['Value']['LongValue']) 154 | 155 | entry['answer'] = answer_text 156 | entry['src'] = src 157 | 158 | 159 | elif query_result["Type"]=="DOCUMENT": 160 | d += 1 161 | if "DocumentTitle" in query_result: 162 | document_title = query_result["DocumentTitle"]["Text"] 163 | #print("Title: " + document_title) 164 | 165 | document_text = query_result["DocumentExcerpt"]["Text"] 166 | src = "Document: [Link]({})".format(query_result['DocumentAttributes'][0]['Value']['StringValue']) 167 | 168 | if len(query_result['DocumentAttributes']) > 1: 169 | src += " and Page: {}".format(query_result['DocumentAttributes'][1]['Value']['LongValue']) 170 | 171 | # if src not in sources_list: 172 | # sources_list.append(src) 173 | # print('document text: ', document_text) 174 | entry['answer'] = document_text 175 | entry['src'] = src 176 | 177 | if len(entry) > 0: 178 | result_set.append(entry) 179 | 180 | # print('Final document_text: ', document_text) 181 | # result = answer_text +' '+document_text 182 | # print('Final result text: ', result) 183 | 184 | # result_dict['snippet'] = result 185 | # result_dict['sources'] = sources_list 186 | 187 | return result_set 188 | 189 | 190 | def GetAnswers(query): 191 | answer = None 192 | sources = '' 193 | if industry.lower() == 'financial services': 194 | index_id = fsi_index_id 195 | elif industry.lower() == 'energy': 196 | index_id = energy_index_id 197 | elif industry.lower() == 'travel and transport': 198 | index_id = travel_index_id 199 | elif industry.lower() == 'legal': 200 | index_id = legal_index_id 201 | else: 202 | index_id = '' 203 | 204 | func = models[model]['func'] 205 | 206 | generated_text = '' 207 | # Kendra calls 208 | results = call_Kendra(query.strip("query:"), index_id) 209 | # Based on model selected 210 | 211 | if len(results) == 0: 212 | generated_text = func(query.strip("query:")) 213 | 214 | if generated_text is None or generated_text == '': 215 | answer = 'Sorry, did not find an answer to your question, please try again or with different input' 216 | elif 'Error' not in generated_text : 217 | answer = str(generated_text) 218 | answer = answer.replace("$","\$") 219 | else: 220 | answer = generated_text + ' Please try again or with different input' 221 | 222 | else: 223 | full_snippet = '' 224 | print('Full results: {}'.format(results)) 225 | 226 | for idx, entry in enumerate(results): 227 | 228 | print('Result Entry : {}'.format(entry)) 229 | if idx <= 3: 230 | full_snippet += entry['answer'] + '\n' 231 | sources += entry['src'] + '\n\n\n' 232 | 233 | formatted_snippet = full_snippet.translate(str.maketrans('','',string.punctuation)) 234 | formatted_snippet = formatted_snippet.replace('\n',' ') 235 | 236 | #st.write("Search results for: {}\n".format(query.strip())) 237 | #for entry in results: 238 | # st.write('- ', entry['answer'].replace("\n",".. ")) 239 | # st.write(' Source ', entry['src']) 240 | 241 | 242 | generated_text = func(formatted_snippet+'. Answer from this text:'+query.strip("query:")) 243 | 244 | #print('generated result text: ', generated_text) 245 | 246 | if generated_text is None or generated_text == '': 247 | answer = 'Sorry, did not find an answer to your question, please try again' 248 | elif 'Error' not in generated_text : 249 | answer = str(generated_text) 250 | answer = answer.replace("$","\$") 251 | answer = answer + 'Document sources are: \n\n' + sources 252 | else: 253 | answer = generated_text + ' Please try again or with different input' 254 | 255 | 256 | return answer 257 | 258 | st.write("**Instructions:** \n - Type your query \n - You will get the top answer explained. If a match was not found in Amazon Kendra, you will get a general answer for your query \n") 259 | input_text = st.text_input('**What are you searching for?**', key='text') 260 | result = '' 261 | if input_text != '': 262 | result = GetAnswers(input_text) 263 | result = result.replace("$","\$") 264 | st.write('\nAnswers from Model') 265 | st.write(result) 266 | 267 | if 'Jumpstart' in model: 268 | st.write("Source: "+ model + ': ' + pref_jumpstart_model ) 269 | else: 270 | st.write('Source: ' + model) 271 | 272 | func = models[model]['func'] 273 | 274 | if result != '': 275 | #if model == 'anthropic claude': 276 | p_text = func('Generate three prompts to query the text: '+ result) 277 | p_text1 = [] 278 | p_text2 = '' 279 | if p_text != '': 280 | p_text = p_text.replace("$","\$") 281 | p_text1 = p_text.split('\n') 282 | for i,t in enumerate(p_text1): 283 | if i > 1: 284 | p_text2 += t.split('?')[0]+'\n\n' 285 | else: 286 | p_text2 += t + '\n\n' 287 | p_summary = p_text2 288 | 289 | st.sidebar.markdown('### Suggested prompts for further insights \n\n' + 290 | p_summary) 291 | 292 | st.sidebar.markdown('### :red[Cost of Bedrock Invocations] \n' 293 | + gen_ai_selector.report_cost()) 294 | -------------------------------------------------------------------------------- /pages/GenAI_product_ideator.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT No Attribution 3 | 4 | Copyright 2023 Amazon Web Services 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 7 | software and associated documentation files (the "Software"), to deal in the Software 8 | without restriction, including without limitation the rights to use, copy, modify, 9 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 14 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 15 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 16 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 17 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | """ 19 | import json 20 | import boto3 21 | import streamlit as st 22 | from PIL import Image 23 | import numpy as np 24 | import matplotlib.pyplot as plt 25 | import base64 26 | import uuid 27 | import os 28 | import sagemaker 29 | from sagemaker import ModelPackage, get_execution_role 30 | from stability_sdk_sagemaker.predictor import StabilityPredictor 31 | from stability_sdk_sagemaker.models import get_model_package_arn 32 | from stability_sdk.api import GenerationRequest, GenerationResponse, TextPrompt 33 | from PIL import Image 34 | import io 35 | import base64 36 | import random 37 | from utils import gen_ai_selector 38 | from utils import cognito_helper 39 | 40 | import pages.imports.sts_assume_role as boto3_session 41 | 42 | autorefresh_session = boto3_session.run_autorefresh_session() 43 | 44 | s3 = autorefresh_session.client('s3') 45 | comprehend = autorefresh_session.client('comprehend') 46 | rekognition = autorefresh_session.client('rekognition') 47 | kendra = autorefresh_session.client("kendra") 48 | textract = autorefresh_session.client("textract") 49 | 50 | iam_role = os.environ['IAM_ROLE'] 51 | 52 | # Get environment variables 53 | bucket = os.environ['bucket'] 54 | im_endpoint_name = os.environ['im_endpoint_name'] 55 | tx_endpoint_name = os.environ['tx_endpoint_name'] 56 | 57 | # Get environment variables 58 | languages = ['English', 'Spanish', 'German', 'Portugese', 'Irish', 'Korean', 'Swedish', 'Norwegian', 'Danish', 'Icelandic', 'Finnish', 'Star Trek - Klingon', 'Star Trek - Ferengi', 'Italian', 'French', 'Japanese', 'Mandarin', 'Tamil', 'Hindi', 'Telugu', 'Kannada', 'Arabic', 'Hebrew'] 59 | 60 | negative_prompt = ( 61 | "ugly, tiling, poorly drawn hands, poorly drawn face, out of frame, extra limbs, \ 62 | disfigured, deformed, body out of frame, bad anatomy, watermark, signature, cut off, \ 63 | low quality, bad art, beginner, windy, amateur, distorted face, blurry, blurred, grainy, \ 64 | draft, low contrast, underexposed, overexposed" 65 | ) 66 | 67 | wallpaper_height=512 68 | wallpaper_width=512 69 | 70 | random_seed = random.randint(1,1000000000) 71 | 72 | available_style_presets = [ 73 | "anime", 74 | "photographic", 75 | "digital-art", 76 | "comic-book", 77 | "fantasy-art", 78 | "line-art", 79 | "analog-film", 80 | "neon-punk", 81 | "isometric", 82 | "low-poly", 83 | "origami", 84 | "modeling-compound", 85 | "cinematic", 86 | "3d-model", 87 | "pixel-art", 88 | "tile-texture", 89 | ] 90 | 91 | st.set_page_config(page_title="GenAI Product Ideator", page_icon="high_brightness") 92 | 93 | if 'stage' not in st.session_state: 94 | st.session_state.stage = 1 95 | if 'login_form_rendered' not in st.session_state: 96 | st.session_state.login_form_rendered = False 97 | if 'login_form_rendered_page' not in st.session_state: 98 | st.session_state.login_form_rendered_page = '' 99 | 100 | cognito_helper.manage_session() 101 | 102 | if not st.session_state["authenticated"]: 103 | cognito_helper.login() 104 | st.stop() 105 | 106 | 107 | st.markdown( 108 | """ 109 | ### :red[Note] 110 | - These demos are for informational purposes only. 111 | - Use these selection of [samples for playing with the demos](https://github.com/aws-samples/gen-ai-samples/sample-artifacts). 112 | - The demos should not be considered as an actual prototype or working version of a proposed solution 113 | """) 114 | st.markdown("# Take your product idea to the next level") 115 | st.sidebar.header("GenAI product ideator") 116 | st.sidebar.markdown("### Make your pick") 117 | 118 | default_style = available_style_presets.index('3d-model') 119 | 120 | wallpaper_style = st.sidebar.selectbox("Wallpaper Style Presets", available_style_presets, index=default_style) 121 | 122 | 123 | industry = '' 124 | industry = st.sidebar.selectbox( 125 | 'Select an industry', 126 | ('Retail', 'Fashion', 'Manufacturing', 'Technology', 'Transport')) 127 | 128 | 129 | 130 | genai_models = gen_ai_selector.genai_models 131 | default_model = gen_ai_selector.default_genai_model_index 132 | model = st.sidebar.selectbox('Select a FM', genai_models, index=default_model) 133 | 134 | models = gen_ai_selector.genai_model_functions 135 | 136 | img_models = { 137 | "bedrock" : gen_ai_selector.find_bedrock_model('bedrock sdxl'), 138 | #"jumpstart" : gen_ai_selector.find_jumpstart_model('sdxl') 139 | } 140 | 141 | 142 | 143 | 144 | def call_sdxl(query): 145 | #output = deployed_model.predict(GenerationRequest(text_prompts=[TextPrompt(text=query)], 146 | 147 | prompt_text = query 148 | 149 | chosen_type = 'bedrock sdxl' if model.startswith('bedrock') else 'jumpstart sdxl' 150 | sd_model = gen_ai_selector.find_bedrock_model('bedrock sdxl') 151 | img_func = sd_model['func'] 152 | 153 | output = img_func(prompt_text, 154 | style_preset="digital-art", 155 | seed = 1885337276, 156 | steps=100, 157 | cfg_scale=10, 158 | image_strength=0.5 159 | ) 160 | return output 161 | 162 | def sdxl_decode_and_show(model_response: GenerationResponse) -> None: 163 | """ 164 | Decodes and displays an image from SDXL output 165 | 166 | Args: 167 | model_response (GenerationResponse): The response object from the deployed SDXL model. 168 | 169 | Returns: 170 | None 171 | """ 172 | artifacts = model_response['artifacts'] 173 | image = artifacts[0]['base64'] 174 | image_data = base64.b64decode(image.encode()) 175 | image = Image.open(io.BytesIO(image_data)) 176 | return image 177 | 178 | 179 | #def query_im_endpoint(text): 180 | # client = boto3.client('runtime.sagemaker') 181 | # payload = { 182 | # "prompt": text, 183 | # "width": 480, 184 | # "height": 480, 185 | # "num_inference_steps": 200, 186 | # "seed": 42, 187 | # "guidance_scale": 8.5 188 | # } 189 | # body = json.dumps(payload).encode('utf-8') 190 | # response = client.invoke_endpoint(EndpointName=im_endpoint_name, ContentType='application/json', Body=body, Accept='application/json;jpeg') 191 | 192 | # return response 193 | 194 | def parse_im_response(query_im_response): 195 | response_dict = json.loads(query_im_response['Body'].read()) 196 | return response_dict['generated_images'], response_dict['prompt'] 197 | 198 | def save_image(img, prmpt): 199 | plt.figure(figsize=(12,12)) 200 | plt.imshow(np.array(img)) 201 | plt.axis('off') 202 | plt.title(prmpt) 203 | prefix = "test-"+str(uuid.uuid4())+".jpg" 204 | plt.savefig("/tmp/"+prefix) 205 | #print("image name before S3 upload is: " + "/tmp/"+prefix) 206 | s3.upload_file("/tmp/"+prefix, bucket, prefix) 207 | img_url = 'http://dzlvehx4kcg5h.cloudfront.net/'+prefix 208 | return img_url 209 | 210 | def GetAnswers(query): 211 | pii_list = [] 212 | answer = None 213 | 214 | #sentiment = comprehend.detect_sentiment(Text=query, LanguageCode='en')['Sentiment'] 215 | resp_pii = comprehend.detect_pii_entities(Text=query, LanguageCode='en') 216 | for pii in resp_pii['Entities']: 217 | if pii['Type'] not in ['NAME', 'AGE', 'ADDRESS','DATE_TIME']: 218 | pii_list.append(pii['Type']) 219 | if len(pii_list) > 0: 220 | answer = "I am sorry but I found PII entities " + str(pii_list) + " in your query. Please remove PII entities and try again." 221 | return answer 222 | query_type = '' 223 | 224 | if query == "cancel": 225 | answer = 'It was swell interacting with you. Thanks for your time.' 226 | return answer 227 | else: 228 | # Call the Stability model to get the image for our query, save it in S3 and build a response card 229 | #response = query_im_endpoint("Detailed image of " + query+" in " + industry.lower()) 230 | #timg, prmpt = parse_im_response(response) 231 | #generated_image_decoded = BytesIO(base64.b64decode(timg[0].encode())) 232 | #generated_image_rgb = Image.open(generated_image_decoded).convert("RGB") 233 | #img_url_new = save_image(generated_image_rgb, prmpt) 234 | st.write("**Example image for your product idea**: \n") 235 | sd_query = "Generate a detailed image of " + query+" in " + industry.lower() 236 | st.image(sdxl_decode_and_show(call_sdxl(sd_query))) 237 | #st.image(img_url_new) 238 | generated_text = '' 239 | prompt_text = 'Create a product description in '+language+' in 200 words for '+ query.strip("query:") 240 | func = models[model]['func'] 241 | answer = func(prompt_text) 242 | answer = answer.replace("$","\$") 243 | return answer 244 | 245 | st.write("**Instructions:** \n - Type a product idea prompt \n - You will see an image, a product description, and press release generated for your product idea") 246 | 247 | 248 | input_text = st.text_input('**What is your product idea?**', key='prod_text') 249 | default_lang_ix = languages.index('English') 250 | language = st.selectbox( 251 | '**Select an output language.** Only Alpha and Beta quadrant languages supported. For new requests, please contact C-3PO', 252 | options=languages, index=default_lang_ix) 253 | key_phrases = '' 254 | answer = None 255 | if input_text != '': 256 | result = GetAnswers(input_text) 257 | result = result.replace("$","\$") 258 | tab1, tab2, tab3, tab4 = st.tabs(["Product description", "Internal memo", "Press release", "Social Media Ad"]) 259 | #c1, c2 = st.columns(2) 260 | with tab1: 261 | st.write("**Description for your product idea**") 262 | st.write(result) 263 | with tab2: 264 | st.write("**Internal memo for your product idea**") 265 | prompt_text = 'Generate an internal memo announcing the launch decision in '+language+' for '+ input_text.strip("query:") 266 | func = models[model]['func'] 267 | answer = func(prompt_text) 268 | answer = answer.replace("$","\$") 269 | st.write(answer) 270 | with tab3: 271 | st.write("**Press release for your product idea**") 272 | prompt_text = 'Generate a press release and some FAQs to help understand the product better in '+language+' for '+ input_text.strip("query:") 273 | func = models[model]['func'] 274 | answer = func(prompt_text) 275 | answer = answer.replace("$","\$") 276 | st.write(answer) 277 | with tab4: 278 | st.write("**Social Media Ad for your product idea**") 279 | prompt_text = 'Generate a catchy trendy social media ad in '+language+' for '+ input_text.strip("query:") 280 | func = models[model]['func'] 281 | answer = func(prompt_text) 282 | answer = answer.replace("$","\$") 283 | st.write(answer) 284 | st.balloons() 285 | 286 | st.sidebar.markdown('### :red[Cost of Bedrock Invocations] \n' 287 | + gen_ai_selector.report_cost()) 288 | -------------------------------------------------------------------------------- /pages/imports/call_bedrock_image.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT No Attribution 3 | 4 | Copyright 2023 Amazon Web Services 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 7 | software and associated documentation files (the "Software"), to deal in the Software 8 | without restriction, including without limitation the rights to use, copy, modify, 9 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 14 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 15 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 16 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 17 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | """ 19 | 20 | import os 21 | import json 22 | import boto3 23 | import requests 24 | 25 | ''' 26 | Parameters: 27 | model_name - From list below or "list_foundation_models" 28 | prompt - Input to the model, string accepted, no default 29 | negative_prompt - Negative prompts to the model, no defaults 30 | task - should be ttoi (Text to Image) or itoi (Image to Image) 31 | style_preset - Style of image to generate 32 | 33 | Models currently supported: 34 | stability.stable-diffusion-xl 35 | 36 | Notes: 37 | I needed to add a bedrock VPC endpoint to avoid timeouts. 38 | Some endpoints take 10-15 seconds to respond, set lambda timeout accordingly. 39 | Expects an environment variable called "secret_name". This is a Secrets Manager 40 | secret that contains AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_DEFAULT_REGION 41 | If your setup calls bedrock locally, make sure your Lambda permissions include bedrock access 42 | and remove the cross-account settings in the bedrock client calls. 43 | Youll need a layer for requests and one for the private version of boto3 that includes bedrock. 44 | https://towardsdatascience.com/building-custom-layers-on-aws-lambda-35d17bd9abbb 45 | Input images should be sent in base64 format 46 | Responses will also be in base64 format. 47 | Example to decode: 48 | Image.open(io.BytesIO(base64.decodebytes(bytes(image_2_b64_str, "utf-8")))) 49 | 50 | Working On: 51 | Better error handling, logging, and status responses 52 | Cohere (when its available) 53 | ''' 54 | 55 | secret_name = os.environ['secret_name'] 56 | 57 | 58 | def call_list_models(): 59 | 60 | aws_access_key, aws_secret_access, region = get_secrets() 61 | bedrock = boto3.client('bedrock',region_name=region, aws_access_key_id=aws_access_key, aws_secret_access_key=aws_secret_access) 62 | 63 | model_list = bedrock.list_foundation_models() 64 | response = [] 65 | for model in model_list['modelSummaries']: 66 | print(model['modelId']) 67 | response.append(model['modelId']) 68 | 69 | return response 70 | 71 | 72 | def call_bedrock_sd(task, prompt, model_name="stability.stable-diffusion-xl", negative_prompts="poorly rendered", style_preset="photographic", init_image=None): 73 | 74 | aws_access_key, aws_secret_access, region = get_secrets() 75 | bedrock = boto3.client('bedrock',region_name=region, aws_access_key_id=aws_access_key, aws_secret_access_key=aws_secret_access) 76 | 77 | if task == "ttoi": 78 | 79 | request = json.dumps({ 80 | "text_prompts": ( 81 | [{"text": prompt, "weight": 1.0}] 82 | + [{"text": negprompt, "weight": -1.0} for negprompt in negative_prompts] 83 | ), 84 | "cfg_scale": 5, 85 | "seed": 5450, 86 | "steps": 70, 87 | "style_preset": style_preset, 88 | }) 89 | 90 | response = bedrock.invoke_model(body=request, modelId=model_name) 91 | response_body = json.loads(response.get("body").read()) 92 | 93 | return response_body["artifacts"][0].get("base64") 94 | 95 | elif task == "itoi": 96 | request = json.dumps({ 97 | "text_prompts": ( 98 | [{"text": prompt, "weight": 1.0}] 99 | + [{"text": negprompt, "weight": -1.0} for negprompt in negative_prompts] 100 | ), 101 | "cfg_scale": 10, 102 | "init_image": init_image, 103 | "seed": 321, 104 | "start_schedule": 0.6, 105 | "steps": 50, 106 | "style_preset": style_preset, 107 | }) 108 | 109 | response = bedrock.invoke_model(body=request, modelId=model_name) 110 | response_body = json.loads(response.get("body").read()) 111 | 112 | return response_body["artifacts"][0].get("base64") 113 | 114 | 115 | def get_secrets(): 116 | headers = {"X-Aws-Parameters-Secrets-Token": os.environ.get('AWS_SESSION_TOKEN')} 117 | secrets_extension_http_port = "2773" 118 | 119 | secrets_extension_endpoint = "http://localhost:" + \ 120 | secrets_extension_http_port + \ 121 | "/secretsmanager/get?secretId=" + \ 122 | secret_name 123 | 124 | r = requests.get(secrets_extension_endpoint, headers=headers) 125 | 126 | secret = json.loads(r.text)["SecretString"] 127 | aws_access_key = json.loads(secret)["AWS_ACCESS_KEY_ID"] 128 | aws_secret_access = json.loads(secret)["AWS_SECRET_ACCESS_KEY"] 129 | region = json.loads(secret)["AWS_DEFAULT_REGION"] 130 | 131 | return aws_access_key, aws_secret_access, region 132 | 133 | -------------------------------------------------------------------------------- /pages/imports/call_bedrock_text.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT No Attribution 3 | 4 | Copyright 2023 Amazon Web Services 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 7 | software and associated documentation files (the "Software"), to deal in the Software 8 | without restriction, including without limitation the rights to use, copy, modify, 9 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 14 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 15 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 16 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 17 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | """ 19 | 20 | import os 21 | import json 22 | import boto3 23 | import requests 24 | 25 | ''' 26 | Parameters: 27 | model_name - From list below or "list_foundation_models" 28 | prompt - Input to the model, string accepted, no default 29 | max_tokens - Configures the maximum number of tokens in the generated response 30 | temperature - 0-1, highest probability (least creative) to lowest probability (most creative) 31 | top_p - defines a cut off based on the sum of probabilities of the potential choices. 32 | top_k - Top K defines the cut off where the model no longer selects the words 33 | 34 | Models currently supported: 35 | amazon.titan-tg1-large 36 | ai21.j2-grande-instruct 37 | ai21.j2-jumbo-instruct 38 | anthropic.claude-instant-v1 39 | anthropic.claude-v1 40 | anthropic.claude-v1-100k 41 | anthropic.claude-v2 42 | anthropic.claude-v2-100k 43 | 44 | Notes: 45 | I needed to add a bedrock VPC endpoint to avoid timeouts. 46 | Some endpoints take 10-15 seconds to respond, set lambda timeout accordingly. 47 | Expects an environment variable called "secret_name". This is a Secrets Manager 48 | secret that contains AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_DEFAULT_REGION 49 | If your setup calls bedrock locally, make sure your Lambda permissions include bedrock access 50 | and remove the cross-account settings in the bedrock client calls. 51 | Youll need a layer for requests and one for the private version of boto3 that includes bedrock. 52 | https://towardsdatascience.com/building-custom-layers-on-aws-lambda-35d17bd9abbb 53 | 54 | Working On: 55 | Better error handling, logging, and status responses 56 | Cohere (when its available) 57 | ''' 58 | 59 | key = os.environ['AWS_ACCESS_KEY_ID'] 60 | secret = os.environ['AWS_SECRET_ACCESS_KEY'] 61 | region = os.environ['AWS_DEFAULT_REGION'] 62 | 63 | 64 | def call_list_models(): 65 | 66 | bedrock = boto3.client('bedrock',region_name=region, aws_access_key_id=key, aws_secret_access_key=secret) 67 | 68 | model_list = bedrock.list_foundation_models() 69 | response = [] 70 | for model in model_list['modelSummaries']: 71 | print(model['modelId']) 72 | response.append(model['modelId']) 73 | 74 | return response 75 | 76 | 77 | def call_bedrock_titan(model_name, prompt_text, max_token_count=512, temperature=1, top_p=1, stop_sequences=[]): 78 | 79 | bedrock = boto3.client('bedrock',region_name=region, aws_access_key_id=key, aws_secret_access_key=secret) 80 | 81 | body = json.dumps({ 82 | "inputText": prompt_text 83 | }) 84 | 85 | response = bedrock.invoke_model( 86 | body=body, 87 | modelId=model_name, 88 | accept="application/json", 89 | contentType="application/json" 90 | ) 91 | 92 | response_body = json.loads(response.get("body").read()) 93 | return response_body.get("results")[0].get("outputText") 94 | 95 | 96 | def call_bedrock_anthropic(model_name, prompt_text, max_tokens=300, temperature=0.5, top_k=250, top_p=1): 97 | 98 | bedrock = boto3.client('bedrock',region_name=region, aws_access_key_id=key, aws_secret_access_key=secret) 99 | 100 | body = json.dumps({ 101 | "prompt": prompt_text, 102 | "max_tokens_to_sample": int(max_tokens), 103 | "temperature": float(temperature), 104 | "top_k": int(top_k), 105 | "top_p": float(top_p) 106 | }) 107 | 108 | response = bedrock.invoke_model( 109 | body=body, 110 | modelId=model_name, 111 | accept="application/json", 112 | contentType="application/json" 113 | ) 114 | 115 | response_body = json.loads(response.get("body").read()) 116 | 117 | return response_body.get("completion") 118 | 119 | 120 | def call_bedrock_jurassic(model_name, prompt_text, max_tokens=200, temperature=0.5, top_p=0.5): 121 | 122 | bedrock = boto3.client('bedrock',region_name=region, aws_access_key_id=key, aws_secret_access_key=secret) 123 | 124 | body = json.dumps({ 125 | "prompt": prompt_text, 126 | "maxTokens": int(max_tokens) 127 | }) 128 | 129 | response = bedrock.invoke_model( 130 | body=body, 131 | modelId=model_name, 132 | accept="application/json", 133 | contentType="application/json" 134 | ) 135 | 136 | response_body = json.loads(response.get("body").read()) 137 | 138 | return response_body.get("completions")[0].get("data").get("text") 139 | -------------------------------------------------------------------------------- /pages/imports/sts_assume_role.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT No Attribution 3 | 4 | Copyright 2023 Amazon Web Services 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 7 | software and associated documentation files (the "Software"), to deal in the Software 8 | without restriction, including without limitation the rights to use, copy, modify, 9 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 14 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 15 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 16 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 17 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | """ 19 | import botocore, boto3, datetime 20 | from botocore.session import get_session 21 | import os 22 | 23 | 24 | # 3600 seconds in an hour, this value should match your role's 25 | # maximum session duration (AWS default is 1 hour). If you're 26 | # role chaining (e.g. saml2aws) 1 hour is a hard limit. 27 | 28 | assume_role_arn = os.getenv('IAM_ROLE') 29 | 30 | def refresh_external_credentials(): 31 | """ Function to get temp creds for assumed role """ 32 | sts_client = boto3.client('sts') 33 | response = sts_client.assume_role( 34 | RoleArn=assume_role_arn, 35 | RoleSessionName="session_name", 36 | DurationSeconds=3600 37 | ) 38 | 39 | temp_credentials = response['Credentials'] 40 | print(f"Assumed role {assume_role_arn} and got temporary credentials.") 41 | 42 | aws_access_key_id=temp_credentials['AccessKeyId'] 43 | aws_secret_access_key=temp_credentials['SecretAccessKey'] 44 | aws_session_token=temp_credentials['SessionToken'] 45 | aws_expiry_time=temp_credentials.get('Expiration').isoformat() 46 | 47 | return { 48 | "access_key": aws_access_key_id, 49 | "secret_key": aws_secret_access_key, 50 | "token": aws_session_token, 51 | "expiry_time": aws_expiry_time 52 | } 53 | 54 | 55 | def run_autorefresh_session(): 56 | 57 | credentials = botocore.credentials.RefreshableCredentials.create_from_metadata( 58 | metadata=refresh_external_credentials(), 59 | refresh_using=refresh_external_credentials, 60 | method="sts-assume-role", 61 | ) 62 | 63 | 64 | session = get_session() 65 | session._credentials = credentials 66 | session.set_config_variable("region", os.environ['AWS_DEFAULT_REGION']) 67 | autorefresh_session = boto3.session.Session(botocore_session=session) 68 | 69 | return autorefresh_session 70 | 71 | 72 | -------------------------------------------------------------------------------- /pushLatestDockerImage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # EDIT following paramters with correct values, including region 4 | export STACK_ID=EDIT_ME 5 | export AWS_ACCOUNT_ID=EDIT_ME 6 | export AWS_DEFAULT_REGION=us-east-1 7 | export GEN_AI_SAMPLE_ECR_REPO=gen-ai-sample-repo # EDIT as necessary 8 | export GEN_AI_SAMPLE_DOCKER_VERSION=0.1 # EDIT as necessary 9 | 10 | export SUFFIX_ID=`echo $STACK_ID | cut -d '/' -f 3 | cut -d '-' -f 4 ` 11 | export GEN_AI_SAMPLE_DOCKER_IMAGE="gen-ai-sample-${SUFFIX_ID}" 12 | export REPO_ID="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${GEN_AI_SAMPLE_ECR_REPO}/${GEN_AI_SAMPLE_DOCKER_IMAGE}" 13 | 14 | #aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${GEN_AI_SAMPLE_ECR_REPO}/${GEN_AI_SAMPLE_DOCKER_IMAGE} 15 | 16 | docker build -t $GEN_AI_SAMPLE_DOCKER_IMAGE:$GEN_AI_SAMPLE_DOCKER_VERSION . 17 | docker tag "${GEN_AI_SAMPLE_DOCKER_IMAGE}:${GEN_AI_SAMPLE_DOCKER_VERSION}" "${REPO_ID}:${GEN_AI_SAMPLE_DOCKER_VERSION}" 18 | aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | docker login --username AWS --password-stdin ${REPO_ID} 19 | docker push "${REPO_ID}:${GEN_AI_SAMPLE_DOCKER_VERSION}" 20 | 21 | 22 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | PyJWT 2 | ai21==1.1.4 3 | anthropic==0.2.10 4 | autopep8 5 | bokeh==2.4.3 6 | boto3 7 | diagrams 8 | gremlinpython 9 | matplotlib 10 | numpy 11 | pandas 12 | pdf2image 13 | pillow 14 | plost 15 | protobuf==3.20.* 16 | pydot 17 | pyflowchart 18 | pypdf 19 | python-jose 20 | qrcode 21 | sagemaker 22 | stability-sdk[sagemaker] @ git+https://github.com/Stability-AI/stability-sdk.git@sagemaker 23 | streamlit 24 | streamlit-analytics 25 | streamlit-bokeh-events 26 | streamlit-chat 27 | streamlit-cognito-auth 28 | streamlit-extras 29 | streamlit-feedback 30 | streamlit-option-menu 31 | streamlit-reveal-slides 32 | streamlit-scrollable-textbox 33 | streamlit_drawable_canvas 34 | textract 35 | -------------------------------------------------------------------------------- /sample-artifacts/FicticiousHotelsFAQ.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/sample-artifacts/FicticiousHotelsFAQ.pdf -------------------------------------------------------------------------------- /sample-artifacts/call-analyzer-samples/sample-call-1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/sample-artifacts/call-analyzer-samples/sample-call-1.wav -------------------------------------------------------------------------------- /sample-artifacts/call-analyzer-samples/sample-call-2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/sample-artifacts/call-analyzer-samples/sample-call-2.wav -------------------------------------------------------------------------------- /sample-artifacts/call-analyzer-samples/sample-call-3.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/sample-artifacts/call-analyzer-samples/sample-call-3.wav -------------------------------------------------------------------------------- /sample-artifacts/call-analyzer-samples/sample-call-4.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/sample-artifacts/call-analyzer-samples/sample-call-4.wav -------------------------------------------------------------------------------- /sample-artifacts/call-analyzer-samples/sample-call-5.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/sample-artifacts/call-analyzer-samples/sample-call-5.wav -------------------------------------------------------------------------------- /sample-artifacts/call-analyzer-samples/sample-call-6.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/sample-artifacts/call-analyzer-samples/sample-call-6.wav -------------------------------------------------------------------------------- /sample-artifacts/code-source-samples/SubtractNumbers.java: -------------------------------------------------------------------------------- 1 | public class SubtractNumbers { 2 | 3 | public static void main(String[] args) { 4 | 5 | int num1 = 10; 6 | int num2 = 5; 7 | 8 | int difference = num1 - num2; 9 | 10 | System.out.println(num1 + " - " + num2 + " = " + difference); 11 | } 12 | 13 | } -------------------------------------------------------------------------------- /sample-artifacts/code-source-samples/add_numbers.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | def adder(a, b): 4 | c == a+b 5 | print("The answer is: " + c) 6 | 7 | adder(1,2) -------------------------------------------------------------------------------- /sample-artifacts/code-source-samples/order_entry.cbl: -------------------------------------------------------------------------------- 1 | IDENTIFICATION DIVISION. 2 | PROGRAM-ID. ORDER-ENTRY. 3 | 4 | ENVIRONMENT DIVISION. 5 | INPUT-OUTPUT SECTION. 6 | FILE-CONTROL. 7 | SELECT ORDER-FILE ASSIGN TO "orders.dat" 8 | ORGANIZATION IS LINE SEQUENTIAL. 9 | 10 | DATA DIVISION. 11 | FILE SECTION. 12 | FD ORDER-FILE. 13 | 01 ORDER-RECORD. 14 | 05 ORDER-NUMBER PIC 9(5). 15 | 05 CUSTOMER-NAME PIC X(30). 16 | 05 ITEM-ORDERED PIC X(20). 17 | 05 ITEM-PRICE PIC 9(4)V99. 18 | 19 | WORKING-STORAGE SECTION. 20 | 01 WS-EOF PIC X(3) VALUE "NO ". 21 | 22 | PROCEDURE DIVISION. 23 | BEGIN. 24 | OPEN INPUT ORDER-FILE 25 | READ ORDER-FILE 26 | AT END MOVE "YES" TO WS-EOF 27 | END-READ 28 | 29 | PERFORM UNTIL WS-EOF = "YES" 30 | DISPLAY ORDER-NUMBER, CUSTOMER-NAME, 31 | ITEM-ORDERED, ITEM-PRICE 32 | READ ORDER-FILE 33 | AT END MOVE "YES" TO WS-EOF 34 | END-READ 35 | END-PERFORM 36 | 37 | CLOSE ORDER-FILE 38 | STOP RUN. -------------------------------------------------------------------------------- /sample-artifacts/content-analyzer-samples/2022-amzn-Shareholder-Letter.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/sample-artifacts/content-analyzer-samples/2022-amzn-Shareholder-Letter.pdf -------------------------------------------------------------------------------- /sample-artifacts/content-analyzer-samples/InvoiceBot.json: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "schemaVersion": "1.0", 4 | "importType": "LEX", 5 | "importFormat": "JSON" 6 | }, 7 | "resource": { 8 | "name": "InvoiceBot", 9 | "version": "3", 10 | "intents": [ 11 | { 12 | "name": "GetInvoiceNotes", 13 | "version": "2", 14 | "fulfillmentActivity": { 15 | "type": "ReturnIntent" 16 | }, 17 | "sampleUtterances": [ 18 | "I would like the invoice notes please", 19 | "invoice notes please", 20 | "Can you show the invoice notes for {invoicenr}", 21 | "I would like the invoice notes for {invoicenr}", 22 | "Please show me the invoice notes for {invoicenr}", 23 | "show me the invoice notes", 24 | "I would like to see the invoice notes" 25 | ], 26 | "slots": [ 27 | { 28 | "sampleUtterances": [], 29 | "slotType": "AMAZON.TVEpisode", 30 | "obfuscationSetting": "NONE", 31 | "slotConstraint": "Required", 32 | "valueElicitationPrompt": { 33 | "messages": [ 34 | { 35 | "contentType": "PlainText", 36 | "content": "Please enter the invoice number" 37 | } 38 | ], 39 | "maxAttempts": 2 40 | }, 41 | "priority": 1, 42 | "name": "invoicenr" 43 | } 44 | ] 45 | }, 46 | { 47 | "name": "GetInvoiceSummary", 48 | "version": "2", 49 | "fulfillmentActivity": { 50 | "type": "ReturnIntent" 51 | }, 52 | "sampleUtterances": [ 53 | "Show me my invoice summary", 54 | "invoice summary please", 55 | "invoice summary", 56 | "summary", 57 | "Can you please get me the invoice summary", 58 | "I would like to review the invoice summary", 59 | "show me the invoice summary" 60 | ], 61 | "slots": [] 62 | }, 63 | { 64 | "name": "GetInvoiceDetails", 65 | "version": "2", 66 | "fulfillmentActivity": { 67 | "type": "ReturnIntent" 68 | }, 69 | "sampleUtterances": [ 70 | "Could you show the invoice details for {invoicenr}", 71 | "show me the invoice details for {invoicenr}", 72 | "invoice details please", 73 | "invoice details", 74 | "show me the invoice details", 75 | "Get me the invoice details for {invoicenr}", 76 | "Get me the invoice details" 77 | ], 78 | "slots": [ 79 | { 80 | "sampleUtterances": [], 81 | "slotType": "AMAZON.TVEpisode", 82 | "obfuscationSetting": "NONE", 83 | "slotConstraint": "Required", 84 | "valueElicitationPrompt": { 85 | "messages": [ 86 | { 87 | "contentType": "PlainText", 88 | "content": "Please enter the invoice number" 89 | } 90 | ], 91 | "maxAttempts": 2 92 | }, 93 | "priority": 1, 94 | "name": "invoicenr" 95 | } 96 | ] 97 | } 98 | ], 99 | "voiceId": "Joanna", 100 | "childDirected": false, 101 | "locale": "en-US", 102 | "idleSessionTTLInSeconds": 300, 103 | "clarificationPrompt": { 104 | "messages": [ 105 | { 106 | "contentType": "PlainText", 107 | "content": "Sorry, can you please repeat that?" 108 | } 109 | ], 110 | "maxAttempts": 5 111 | }, 112 | "abortStatement": { 113 | "messages": [ 114 | { 115 | "contentType": "PlainText", 116 | "content": "Sorry I didn't understand that request, please try again" 117 | } 118 | ] 119 | }, 120 | "detectSentiment": false 121 | } 122 | } -------------------------------------------------------------------------------- /sample-artifacts/content-analyzer-samples/Sample-Excel-Household-Organizer.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/sample-artifacts/content-analyzer-samples/Sample-Excel-Household-Organizer.xlsx -------------------------------------------------------------------------------- /sample-artifacts/content-analyzer-samples/SampleInvoice.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/sample-artifacts/content-analyzer-samples/SampleInvoice.xlsx -------------------------------------------------------------------------------- /sample-artifacts/content-analyzer-samples/SimpleServiceInvoice1.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/sample-artifacts/content-analyzer-samples/SimpleServiceInvoice1.xlsx -------------------------------------------------------------------------------- /sample-artifacts/content-analyzer-samples/amzn-annualreport-2022.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/sample-artifacts/content-analyzer-samples/amzn-annualreport-2022.pdf -------------------------------------------------------------------------------- /sample-artifacts/content-analyzer-samples/buggy_code.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | def adder(a, b): 4 | c == a+b 5 | print("The answer is: " + c) 6 | 7 | adder(1,2) -------------------------------------------------------------------------------- /sample-artifacts/content-analyzer-samples/sample-presentation.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/sample-artifacts/content-analyzer-samples/sample-presentation.pptx -------------------------------------------------------------------------------- /sample-artifacts/content-analyzer-samples/sample-word.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/sample-artifacts/content-analyzer-samples/sample-word.docx -------------------------------------------------------------------------------- /sample-artifacts/general/content/empty-file.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/gen-ai-demos/ac2ccef9c54125e4f2477fa4a7a47a94b49e50e6/sample-artifacts/general/content/empty-file.txt -------------------------------------------------------------------------------- /sample-artifacts/personalize/hotel-recommendations/hotel-metadata.csv: -------------------------------------------------------------------------------- 1 | BRAND,PRICE,DESCRIPTION,ITEM_ID 2 | Apex London Wall Hotel,196,"This 4-star boutique hotel adds lots of style to London Square Mile. Tucked down a quiet street, this city centre hotel strikes the perfect balance of luxury and leisure. The Lampery, Copthall Avenue is perfect for wining, dining and relaxing, plus, our ideal location makes exploring easy. We have everything you need and more, so whether you’re visiting for work or play, find yourself longing to come back and stay.",92f823bb-91ee-483c-8d1b-656ad744f952 3 | Corinthia Hotel London,1010,"Forbes Travel Guide - Perched on Whitehall Place just south of Trafalgar Square, Corinthia London is a chic, city-center retreat that might just make you feel like a visiting royal. The 283 spacious guest rooms are contemporary in look yet elegantly appointed, and you’ll discover great cityscape views along with sumptuous bathrooms outfitted with heated marble floors",ebead615-7734-4520-b03b-9007e134829e 4 | The Savoy,700,"Welcome to The Savoy, a place where history and iconic elegance mingles with new-world sophistication. A destination for generations, and a world-famous name, celebrated for sublime service, and graced by stars, dignitaries and the global jet-set… where Art Deco rubs shoulders with English Edwardian, and exceptional dining blends with contemporary cocktails. The hotel’s 267 luxury rooms and suites celebrate The Savoy’s dual historical influences, featuring either elegant English Edwardian design or sensational Art Deco style",3b64bb4c-b2b6-49fb-a6a1-c6ed3fb9551a 5 | Rhodes Hotel,104,"Modern hotel rooms with air conditioning, in two classical heritage listed Georgian townhouses located next to Paddington station, Lancaster Gate & Hyde Park. We are a small friendly hotel with rooms to suit everyone from solo travellers to couples and families, and standard rooms to deluxe. Excellent central location, within a short walk going east you arrive at Marble Arch & Oxford Street and to the west there is Bayswater and Notting Hill. Rhodes Hotel is walking distance from major transport links offering many bus and train stations and with easy access to London's world famous shopping, attractions, gourmet experiences and business districts.",79039534-2f93-435f-8bf0-af5d2faa2d52 6 | Mondrian London at Sea Containers,277,"With a design reminiscent of a 1920s transatlantic cruise liner, award-winning food and drink outlets and an electric energy, Sea Containers London is the remarkable Southbank hotel. It’s a destination where glamour meets brutalism – and it's your London anchor on the River Thames. A space to unwind, recharge and regroup, our guest rooms are the ideal South Bank base from which to explore London. Whether you opt for a standard room, or book into a river view suite, you’re guaranteed a memorable evening.",36ac7f94-b20d-4cd5-9dc9-49561dc1cf08 7 | "Mandarin Oriental Hyde Park, London",772,"Internationally acclaimed designer, Joyce Wang, drew inspiration from the natural beauty of Hyde Park and the 20th century Golden Age of travel to create our exquisite rooms and suites. With art deco-inspired features and carefully curated artworks, Mandarin Oriental Hyde Park, London is the perfect place to stay in iconic London.",9c3ae205-df0e-4c37-aed5-0ba586018cc4 8 | The Dorchester,882,"Welcome to a hotel alive with a vibrant spirit and convivial soul. A hotel that captures the energy of London and matches its pace, stride for stride. Welcome to The Dorchester. We like to call our hotel a ‘village’ because it feels like a lively, welcoming community, shaped by the dynamic spirit of London. You could spend a whole day here exploring our restaurants and bars, pausing only to sink into an armchair and take in the atmosphere.",30d41eaf-f587-4dc7-bd22-4204294f0aaf 9 | A To Z Hotel,69,"The A to Z hotel is a newly refurbished, comfortable, convenient and affordable budget hotel in West London.",be4e2162-3a76-426d-a51c-b71fc5481c28 10 | Ridgemount Hotel,207,"The Ridgemount Hotel is in the Bloomsbury area of Central London. Its location is unbeatable: just a short walk to The British Museum, Oxford Street, Covent Garden, Soho, Piccadilly and the West End. The hotel has 32 clean and comfortable rooms that are set over four floors of two Georgian townhouses. Suitable for families as well as solo travellers, each of our rooms has fresh linens, smart TVs, tea / coffee making facilities and smart ensuite shower rooms. Full English breakfast is served in the light and airy dining room; with a selection of tea / coffee and hot chocolate as well as cereals, toasts on offer.",9716b878-6bfa-4d0f-a312-3b2115b27175 11 | "The Wellesley Knightsbridge, a Luxury Collection Hotel, London",531,"Overlooking the Royal Hyde Park amidst the glamour of Knightsbridge, The Wellesley combines sophisticated luxury with captivating grandeur and uncompromising service. The bedrooms are beautifully finished with contemporary touches and elegant artwork that pays homage to the building’s Art Deco past. We have married luxurious expressions of deco grandeur with the personal attentiveness of a true boutique experience to create an exquisite jewel for the discerning traveller.",1e60357d-ecd7-401d-8516-78f0e4376e5f 12 | The Rembrandt,207,"A favourite of independent business and leisure travellers from all over the world, this 4-star hotel gets the details right: complimentary WiFi, English breakfast, a popular lounge bar and restaurant, and discounted use of the adjacent spa and swimming pool at Aquilla Health and Fitness Club.",7476646e-1b7d-4f4c-ba76-6f96edbf9192 13 | London Guest House,83,"London Guest House is a friendly, family run Bed and Breakfast in the heart of West London. Located a short distance from Central London, it is ideal for business people working in the area or holiday-makers looking for a quieter alternative to the busy city.",38735c7f-f5ac-4357-9b6c-c4c8654b3717 14 | "Hotel Xenia, Autograph Collection",205,"Inspired by the ancient Greek concept of hospitality, our 4-star Hotel Xenia, Autograph Collection welcomes guests to the centre of Kensington, one of London's most cherished neighbourhood. The hotel is a boutique retreat in the centre of it all, replete with 4-star accommodations, two bars and fine dining at La Terrazza. Easily walk from our prime location to some of the area's most famous historic attractions, including Hyde Park, Royal Albert Hall, Kensington Palace, Knightsbridge and Kensington High Street.",eacbad21-dc9f-4d99-a991-18ffff22d529 15 | "Bulgari Hotel, London",806,"Located in Knightsbridge on the edge of Hyde Park, Bulgari Hotel London is both a haven of calm in the centre of the city and yet under a minute’s walk from such landmarks as the famous Harrods department store. Since opening in 2012, Bulgari has set new standards among the luxury hotels of the British capital. Elegant contemporary architecture and Bulgari’s legendary flair for design are matched by class-leading quality of service.",961e4321-ae4b-4c1c-aa81-60bf971f1395 16 | The Lanesborough,880,"Awarded No. 1 Hotel in London in the Travel + Leisure World's Best Awards, on the doorstep of Hyde Park, just a short walk from Harrods, Harvey Nichols and London’s most exclusive shopping district; Sloane Street and Knightsbridge, this grand luxury mansion has undergone an inspired renovation by the famed interior designer Alberto Pinto. The hotel is home to 93 luxurious suites and bedrooms, modern British dining at The Lanesborough Grill, the vibrant Library Bar and Garden Room and the magnificent Lanesborough Club & Spa.",f35bbbf6-ee07-4057-9894-6a8584bc3ffc 17 | 45 Park Lane - Dorchester Collection,1174,"45 Park Lane is a vibrant beacon of contemporary culture in a luxury hotel. An invigorating blend of art and landmark architecture in the middle of classical London. You’re our guest, not a room number. As unique as a fingerprint, with your own plans, needs and expectations. Because of this, 45 Park Lane offers an unprecedented approach to service during your stay. Your very own host will be on hand as butler, concierge and personalised bank of useful knowledge.",320dc0df-8bb1-44a6-8f63-7d8b9b6db458 18 | Marble Arch Hotel,554,"Welcome to The Marble Arch London, a contemporary five star boutique hotel that personifies the old adage 'good things come in small packages'. In the heart of London, The Marble Arch London is a petite but perfectly formed urban escape. Ideally located within strolling distance of Oxford Street and easy reach of London's landmarks, this chic property offers an idyllic setting in which to experience the best that London has to offer while making memories that will last a lifetime. Boasting sophisticated rooms with a range of modern amenities such as complimentary broadband and Wi-Fi, LCD TV with satellite channels, tea and coffee making facilities, and in-room safe, The Marble Arch London is truly an ideal accommodation. With its enviable location and chic accommodation, The Marble Arch London has everything you could possibly want for a memorable stay in London.",30600d9e-6a04-4075-a6ca-8fe0c37b2279 19 | Newham Hotel,67,"In adjoining converted homes, this straightforward hotel is 0.3 miles from Forest Gate train station with services into London Liverpool Street, and 6 miles from London Bridge. Straightforward rooms have en suite bathrooms with power showers, flat-screen TVs, free Wi-Fi, and tea and coffeemaking facilities. English breakfast is included. There's also a bar-lounge with a big-screen TV. Free off-street parking is available.",b0bc239f-76f8-41a9-b2b4-983e0edb2e53 20 | Hartley Hotel,79,"Set in the cosmopolitan district of Forest Gate, this no-frills budget hotel is a 10-minute walk from Forest Gate tube station, 3.1 miles from Westfield Stratford City shopping centre and 4.4 miles from ExCeL London conference centre. The unfussy rooms sleep up to 4 and have basic furnishings, plus flat-screen TVs and free Wi-Fi. Standard rooms have shared bathrooms, while upgraded rooms include en suite facilities.",f1d6663f-3af2-4779-93b0-ef57c7e02cb4 21 | City View Hotel,77,"City View Hotel is located in Bethnal Green, East London; an exciting part of the city, buzzing with cool bars and clubs alongside fascinating cultural attractions and historic buildings like the Museum of Childhood, Geffrye Museum and Whitechapel Art Gallery. We offer a range of rooms: keep costs down in a single or double with access to shared bathrooms, or enjoy the privacy of your own en-suite bathroom in a double, twin or triple.",26d7b885-d1a4-4950-8e83-afb412e681fa -------------------------------------------------------------------------------- /updateEcsService.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # EDIT following paramters with correct stack id and region 4 | export STACK_ID=EDIT_ME 5 | export AWS_DEFAULT_REGION=us-east-1 6 | 7 | export GEN_AI_ECS_CLUSTER_PREFIX=GenAISamplesECSCluster 8 | export GEN_AI_ECS_SERVICE_PREFIX=GenAISamplesECSService 9 | export SUFFIX_ID=`echo $STACK_ID | cut -d '/' -f 3 | cut -d '-' -f 4 ` 10 | 11 | aws ecs update-service --region ${AWS_DEFAULT_REGION} \ 12 | --cluster "${GEN_AI_ECS_CLUSTER_PREFIX}-${SUFFIX_ID}" \ 13 | --service "${GEN_AI_ECS_SERVICE_PREFIX}-${SUFFIX_ID}" \ 14 | --force-new-deployment --query 'service'.'serviceName' 15 | -------------------------------------------------------------------------------- /utils/llm_pricing.csv: -------------------------------------------------------------------------------- 1 | model_id,region,input_token_price,output_token_price 2 | ai21.j2-mid, all, 0.0125, 0.0125 3 | ai21.j2-ultra, all, 0.0188, 0.0188 4 | amazon.titan-text-lite,us, 0.0003, 0.0004 5 | amazon.titan-text-express, us, 0.0008, 0.0016 6 | amazon.titan-embedding-text, us, 0.0001 7 | amazon.titan-text-express, ap, 0.0011, 0.0022 8 | amazon.titan-embedding-text, ap, 0.0002 9 | amazon.titan-text-express, eu, 0.0012, 0.0023 10 | amazon.titan-embedding-text, eu, 0.0002 11 | amazon.titan-text-express, us-gov, 0.0008, 0.0016 12 | anthropic.claude-v3-haiku,us, 0.00025, 0.00125 13 | anthropic.claude-v3-sonnet,us, 0.003, 0.015 14 | anthropic.claude-v2,all,0.008,0.024 15 | anthropic.claude-instant-v1,all,0.008,0.0024 16 | #anthropic.claude-v2,ap,0.008,0.024 17 | #anthropic.claude-instant-v1,ap,0.008,0.0024 18 | meta.llama2-13b-chat-v1,all, 0.00075,0.001 19 | meta.llama2-70b-chat-v1,all, 0.00195,0.00256 20 | mistral.mistral-7b-instruct,all, 0.00015,0.0002 21 | mistral.mistral-8x7b-instruct,all, 0.00045,0.0007 22 | 23 | 24 | 25 | --------------------------------------------------------------------------------