diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f0739ec1..b146b5a60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [5.4.0] - 2023-07-27 + +__*Note: we recommend that you first deploy these changes in a non-production environment. This is true for all releases, but especially important for minor and major releases.*__ + +### Added + +- New (optional) query disambiguation and text generation features through the use of Large Language Models (LLMs) to enable enhanced conversational chat and response synthesis. Details at [README](docs/LLM_Retrieval_and_generative_question_answering/README.md) + - In order to provide this functionality, the solution will provision an inference endpoint hosted on Amazon SageMaker + - If enabled, this has cost implications. Please [refer to the IG](https://docs.aws.amazon.com/solutions/latest/qnabot-on-aws/plan-your-deployment.html#cost) to see cost estimates +- [App Registry integration](https://docs.aws.amazon.com/servicecatalog/latest/arguide/intro-app-registry.html), QnABot will now register an application in System Manager to enable various application management tools + +### Updated + +- Lambda runtimes updated to NodeJS 18 +- Python runtimes updated to Python 3.10 +- Security patches for npm and pip packages + ## [5.3.5] - 2023-07-12 ### Updated diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 793ba261f..6ca294d08 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,25 +1,59 @@ -# Contributing to the QnABot +# Contributing Guidelines -Contributions to the QnABot should be made via GitHub [pull -requests](https://github.com/aws-solutions/qnabot-on-aws/pulls) and discussed using -GitHub [issues](https://github.com/aws-solutions/qnabot-on-aws/issues). +Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional +documentation, we greatly value feedback and contributions from our community. -## Before you start +Please read through this document before submitting any issues or pull requests to ensure we have all the necessary +information to effectively respond to your bug report or contribution. -If you would like to make a significant change, it's a good idea to first open -an issue to discuss it. +## Reporting Bugs/Feature Requests -## Making the request +We welcome you to use the GitHub issue tracker to report bugs or suggest features. -Development takes place against the `develop` branch of this repository and pull -requests should be opened against that branch. +When filing an issue, please check [existing open](https://github.com/aws-solutions/qnabot-on-aws/issues), or [recently closed](https://github.com/aws-solutions/qnabot-on-aws/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already +reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: -## Testing +- A reproducible test case or series of steps +- The version of our code being used +- Any modifications you've made relevant to the bug +- Anything unusual about your environment or deployment -Any contributions should pass all tests, including those not run by our -current CI system. +## Contributing via Pull Requests -You may run all test by running the `make test`. +Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: -For significant changes, we may ask you to sign a [Contributor License -Agreement](http://en.wikipedia.org/wiki/Contributor_License_Agreement). +1. You are working against the latest source on the _develop_ branch. +2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. +3. You open an issue to discuss any significant work - we would hate for your time to be wasted. + +To send us a pull request, please: + +1. Fork the repository. +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. +3. Ensure local tests pass. +4. Commit to your fork using clear commit messages. +5. Send us a pull request, answering any default questions in the pull request interface. +6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. + +GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and +[creating a pull request](https://help.github.com/articles/creating-a-pull-request/). + +## Finding contributions to work on + +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'](https://github.com/aws-solutions/qnabot-on-aws/labels/help%20wanted) issues is a great place to start. + +## Code of Conduct + +This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). +For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact +opensource-codeofconduct@amazon.com with any additional questions or comments. + +## Security issue notifications + +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. + +## Licensing + +See the [LICENSE](https://github.com/aws-solutions/qnabot-on-aws/blob/main/LICENSE.txt) file for our project's licensing. We will ask you to confirm the licensing of your contribution. + +We may ask you to sign a [Contributor License Agreement (CLA)](https://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. \ No newline at end of file diff --git a/NOTICE.txt b/NOTICE.txt index fdefe5541..c96678891 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -22,6 +22,7 @@ This software includes third party software subject to the following copyrights: @babel/preset-stage-2 under the Massachusetts Institute of Technology (MIT) license ajv under the Massachusetts Institute of Technology (MIT) license alexa-sdk under the Apache License Version 2.0 +arrow under the Apache License Version 2.0 async-mutex under the Massachusetts Institute of Technology (MIT) license autosize under the Massachusetts Institute of Technology (MIT) license aws-lex-web-ui under the Amazon Software License @@ -37,10 +38,14 @@ babel-preset-env under the Massachusetts Institute of Technology (MIT) license babel-preset-es2015 under the Massachusetts Institute of Technology (MIT) license babel-preset-es2015-ie the Massachusetts Institute of Technology (MIT) license beautifulsoup under Massachusetts Institute of Technology (MIT) License +beautifulsoup4 under the Massachusetts Institute of Technology (MIT) license bluebird under the Massachusetts Institute of Technology (MIT) license body-parser under the Massachusetts Institute of Technology (MIT) license +boto3 under the Apache License Version 2.0 +botocore under the Apache License Version 2.0 bowser under the Massachusetts Institute of Technology (MIT) license canvasapi under Massachusetts Institute of Technology (MIT) License +cfn-lambda under the Massachusetts Institute of Technology (MIT) license cfn-response under the Amazon Software License chalk under the Massachusetts Institute of Technology (MIT) license chrome-aws-lambda under the Massachusetts Institute of Technology (MIT) license @@ -48,18 +53,24 @@ clean-deep under the Massachusetts Institute of Technology (MIT) license clipboard under the Massachusetts Institute of Technology (MIT) license commander under the Massachusetts Institute of Technology (MIT) license copy-webpack-plugin under the Massachusetts Institute of Technology (MIT) license -crypto-js under the Massachusetts Institute of Technology (MIT) license +crhelper under the Apache License Version 2.0 css-loader under the Massachusetts Institute of Technology (MIT) license +defusedxml under the Python Software Foundation License Version 2 dir-loader under the Massachusetts Institute of Technology (MIT) license +elasticsearch under the Apache License Version 2.0 exports-loader under the Massachusetts Institute of Technology (MIT) license express under the Massachusetts Institute of Technology (MIT) license faker under the Massachusetts Institute of Technology (MIT) license file-saver under the Massachusetts Institute of Technology (MIT) license +filelock under the Unlicense license handlebars under the Massachusetts Institute of Technology (MIT) license handlebars-loader under the Massachusetts Institute of Technology (MIT) license highlight.js under BSD-3-Clause license html-webpack-plugin under the Massachusetts Institute of Technology (MIT) license +http-aws-es under the Massachusetts Institute of Technology (MIT) license idle-vue under the Massachusetts Institute of Technology (MIT) license +intercept-stdout under the Massachusetts Institute of Technology (MIT) license +jmespath under the Massachusetts Institute of Technology (MIT) license js-cache under the Massachusetts Institute of Technology (MIT) license jsdom under the Massachusetts Institute of Technology (MIT) license jsdom-global under the Massachusetts Institute of Technology (MIT) license @@ -71,6 +82,8 @@ JSONPath under the Massachusetts Institute of Technology (MIT) license jsonschema under the Massachusetts Institute of Technology (MIT) license jsonwebtoken under the Massachusetts Institute of Technology (MIT) license jszip under the Massachusetts Institute of Technology (MIT) license +jwks-rsa under the Massachusetts Institute of Technology (MIT) license +langchain under the Massachusetts Institute of Technology (MIT) license lodash under the Massachusetts Institute of Technology (MIT) license lodash-webpack-plugin under the Massachusetts Institute of Technology (MIT) license marked under the Massachusetts Institute of Technology (MIT) license @@ -85,6 +98,9 @@ pug under the Massachusetts Institute of Technology (MIT) license pug-loader under the Massachusetts Institute of Technology (MIT) license pug-plain-loader under the Massachusetts Institute of Technology (MIT) license pug-runtime under the Massachusetts Institute of Technology (MIT) license +py-serializable under the Apache License Version 2.0 +python-dateutil under the Apache License Version 2.0 and BSD License +pytz under the Massachusetts Institute of Technology (MIT) license query-string under the Massachusetts Institute of Technology (MIT) license querystring under the Massachusetts Institute of Technology (MIT) license querystring-browser under the Massachusetts Institute of Technology (MIT) license @@ -92,13 +108,17 @@ quick-lru under the Massachusetts Institute of Technology (MIT) license range under the Massachusetts Institute of Technology (MIT) license raw-loader under the Massachusetts Institute of Technology (MIT) license raw-text under the Massachusetts Institute of Technology (MIT) license +read-excel-file under the Massachusetts Institute of Technology (MIT) license recursive-readdir under the Massachusetts Institute of Technology (MIT) license require-dir under the Massachusetts Institute of Technology (MIT) license roboto-fontface under the Apache License Version 2.0 +s3transfer under the Apache License Version 2.0 sass under the Massachusetts Institute of Technology (MIT) license sass-loader under the Massachusetts Institute of Technology (MIT) license simple-encryptor under the Massachusetts Institute of Technology (MIT) license slackify-markdown under the Massachusetts Institute of Technology (MIT) license +soupsieve under the Massachusetts Institute of Technology (MIT) license +static-eval under the Massachusetts Institute of Technology (MIT) license strip-ansi under the Massachusetts Institute of Technology (MIT) license style-loader under the Massachusetts Institute of Technology (MIT) license stylus under the Massachusetts Institute of Technology (MIT) license @@ -123,5 +143,4 @@ webpack-bundle-analyzer under the Massachusetts Institute of Technology (MIT) li webpack-cli under the Massachusetts Institute of Technology (MIT) license webpack-dev-server under the Massachusetts Institute of Technology (MIT) license webpack-merge under the Massachusetts Institute of Technology (MIT) license -webpack-s3-plugin under the Massachusetts Institute of Technology (MIT) license -xlsx under the Apache License Version 2.0 +webpack-s3-plugin under the Massachusetts Institute of Technology (MIT) license \ No newline at end of file diff --git a/README.md b/README.md index 71c41f117..51cdfdf8b 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,9 @@ The high-level process flow for the solution components deployed with the AWS Cl 1. The admin deploys the solution into their AWS account, opens the Content Designer UI or [Amazon Lex](https://aws.amazon.com/lex/) web client, and uses [Amazon Cognito](https://aws.amazon.com/cognito/) to authenticate. -2. After authentication, [Amazon CloudFront](http://aws.amazon.com/cloudfront/) and [Amazon S3](http://aws.amazon.com/s3/) deliver the contents of the Content Designer UI. +2. After authentication, [Amazon API Gateway](http://aws.amazon.com/api-gateway/) and [Amazon S3](http://aws.amazon.com/s3/) deliver the contents of the Content Designer UI. -3. The admin configures questions and answers in the Content Designer and the UI sends requests to [Amazon API Gateway](http://aws.amazon.com/api-gateway/) to save the questions and answers. +3. The admin configures questions and answers in the Content Designer and the UI sends requests to Amazon API Gateway to save the questions and answers. 4. The `Content Designer` [AWS Lambda](http://aws.amazon.com/lambda/) function saves the input in [Amazon OpenSearch Service](http://aws.amazon.com/opensearch-service/) in a questions bank index. If using [text embeddings](docs/semantic_matching_using_LLM_embeddings/README.md), these requests will first pass through a ML model hosted on [Amazon SageMaker](https://aws.amazon.com/sagemaker/) to generate embeddings before being saved into the question bank on OpenSearch. @@ -32,9 +32,11 @@ The high-level process flow for the solution components deployed with the AWS Cl 6. Amazon Lex forwards requests to the `Bot Fulfillment` AWS Lambda function. Users can also send requests to this Lambda function via [Amazon Alexa](https://developer.amazon.com/en-US/alexa) devices. -7. The `Bot Fulfillment` AWS Lambda function takes the users input and uses [Amazon Comprehend](https://aws.amazon.com/comprehend/) and [Amazon Translate](https://aws.amazon.com/translate/) (if necessary) to translate non-English requests to English and then looks up the answer in in Amazon OpenSearch Service. If using [text embeddings](docs/semantic_matching_using_LLM_embeddings/README.md), these requests will first pass through a ML model hosted on Amazon SageMaker to generate an embedding to compare with those saved in the question bank on OpenSearch. If an [Amazon Kendra](https://aws.amazon.com/kendra/) index is configured, the `Bot Fulfillment` function also sends a request to that index. +7. The `Bot Fulfillment` AWS Lambda function takes the users input and uses [Amazon Comprehend](https://aws.amazon.com/comprehend/) and [Amazon Translate](https://aws.amazon.com/translate/) (if necessary) to translate non-English requests to English and then looks up the answer in in Amazon OpenSearch Service. If using LLM features such as [text generation](docs/LLM_Retrieval_and_generative_question_answering/README.md) and [text embeddings](docs/semantic_matching_using_LLM_embeddings/README.md), these requests will first pass through various ML models hosted on Amazon SageMaker to generate the search query and embeddings to compare with those saved in the question bank on OpenSearch. -8. User interactions with the `Bot Fulfillment` function generate logs and metrics data, which is sent to [Amazon Kinesis Data Firehose](http://aws.amazon.com/kinesis/data-firehose/) then to Amazon S3 for later data analysis. +8. If an [Amazon Kendra](https://aws.amazon.com/kendra/) index is [configured for fallback](docs/Kendra_Fallback_README.md), the `Bot Fulfillment` AWS Lambda function forwards the request to Kendra if no matches were returned from the OpenSearch question bank. The text generation LLM can optionally be used to create the search query and to synthesize a response given the returned document excerpts. + +9. User interactions with the `Bot Fulfillment` function generate logs and metrics data, which is sent to [Amazon Kinesis Data Firehose](http://aws.amazon.com/kinesis/data-firehose/) then to Amazon S3 for later data analysis. Refer to the [implementation guide](https://docs.aws.amazon.com/solutions/latest/qnabot-on-aws) for detailed instructions on deploying QnABot in your AWS account. diff --git a/VPCSupportREADME.md b/VPCSupportREADME.md index 1393d747f..d9de2d616 100644 --- a/VPCSupportREADME.md +++ b/VPCSupportREADME.md @@ -7,8 +7,8 @@ This feature allows deployment of QnABot components within VPC infrastructure vi referencing the template in S3 using https://solutions-reference.s3.amazonaws.com/qnabot-on-aws/latest/qnabot-on-aws-vpc.template. This template is made available for use as a separate installation mechanism. It is not the default template utilized in the -public distribution. Please take care in deploying QnABot in VPC. The Elasticsearch Cluster becomes private to the VPC. In addition, -the QnABot Lambda functions installed by the stack will be attached to subnets in the VPC. The Elasticsearch cluster is no longer available +public distribution. Please take care in deploying QnABot in VPC. The OpenSearch Cluster becomes private to the VPC. In addition, +the QnABot Lambda functions installed by the stack will be attached to subnets in the VPC. The OpenSearch cluster is no longer available outside of the VPC. The Lambdas attached to the VPC allow communication with the cluster. Two additional parameters are required by this template. @@ -23,7 +23,7 @@ In order to deploy QnABot within a VPC two requirements must be met: 1. A fully functioning VPC with a minimum of two private subnets spread over two availability zones is required. These private VPC subnets should have access to AWS services. This can be accomplished using NAT Gateway with proper IGW configuration / routing. Other third party gateway implementations can be used that provide access to AWS services. - - if using Sagemaker based [text embeddings](docs/semantic_matching_using_LLM_embeddings/README.md) you will need to create a VPC Gateway Endpoint for S3 (this is __required__ to enable SageMaker to download the model) and a VPC Interface Endpoint for SageMaker (this is _optional_; however, enables invocations of the SageMaker Runtime endpoint to remain on the VPC). Additional resources to help with configuration can be found at: + - if using Sagemaker based [text embeddings](docs/semantic_matching_using_LLM_embeddings/README.md) or [text generation](docs/LLM_Retrieval_and_generative_question_answering/README.md) you will need to create a VPC Gateway Endpoint for S3 (this is __required__ to enable SageMaker to download the model) and a VPC Interface Endpoint for SageMaker (this is _optional_; however, enables invocations of the SageMaker Runtime endpoint to remain on the VPC). Additional resources to help with configuration can be found at: - [Give SageMaker Hosted Endpoints Access to Resources in Your Amazon VPC](https://docs.aws.amazon.com/sagemaker/latest/dg/host-vpc.html) - [Connect to SageMaker Through a VPC Interface Endpoint](https://docs.aws.amazon.com/sagemaker/latest/dg/interface-vpc-endpoint.html) - [AWS PrivateLink pricing](https://aws.amazon.com/privatelink/pricing/) @@ -38,7 +38,7 @@ In order to deploy QnABot within a VPC two requirements must be met: ### Deployment -Deploying Elasticsearch cluster into a VPC requires creating a service linked role for es. You can execute the following command +Deploying OpenSearch cluster into a VPC requires creating a service linked role for es. You can execute the following command using credentials for the target account. ``` @@ -58,8 +58,8 @@ To switch to a different mode, you would need to perform a fresh install.** Two new parameters are required when deploying within a VPC -Select a pre-configured security group. This security group must enables inbound communication to -the Elasticsearch cluster on port 443. +Select a pre-configured security group. This security group must enable inbound communication to +the OpenSearch cluster on port 443. Select a minimum of two Private Subnets spread over two availability zones. These private subnets must have NAT configured to allow communication to other AWS services. Do not @@ -69,10 +69,10 @@ Once these are configured, launch the template. ### Behavior of the system after deployment -- This template attaches the Elasticsearch cluster and Lambdas to the private subnets. Communication +- This template attaches the OpenSearch cluster and Lambdas to the private subnets. Communication between these components occurs within the VPC. -- The Kibana dashboard provided within the Elasticsearch cluster is only available +- The Kibana dashboard provided within the OpenSearch cluster is only available within the VPC. Users desiring access to the Kibana dashboard must have access via VPN or Direct Connect to the VPC. @@ -81,7 +81,7 @@ Once these are configured, launch the template. ### Accessing Kibana in VPC -This template deploys ElasticSearch and Kibana within a VPC's Private Subnets. By default, there are +This template deploys OpenSearch and Kibana within a VPC's Private Subnets. By default, there are no means of accessing kibana, and further actions are required to proceed in doing so. Since Kibana is already integrated with Cognito for authentication, the following actions can take diff --git a/bin/URL.sh b/bin/URL.sh index 0aefcd5e4..a1be03a10 100755 --- a/bin/URL.sh +++ b/bin/URL.sh @@ -1,9 +1,9 @@ -#! /bin/bash +#! /bin/bash __dirname="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -export AWS_PROFILE=$(node -e "console.log(require('$__dirname'+'/../config').profile)") +export AWS_PROFILE=$(node -e "console.log(require('$__dirname'+'/../config.json').profile)") # If profile specified from config file does not exist, allow cli to move on to using instance profile aws configure get aws_access_key_id --profile $AWS_PROFILE || unset AWS_PROFILE -export AWS_DEFAULT_REGION=$(node -e "console.log(require('$__dirname'+'/../config').region)") +export AWS_DEFAULT_REGION=$(node -e "console.log(require('$__dirname'+'/../config.json').region)") OUTPUT=$($__dirname/exports.js dev/bootstrap) BUCKET=$( echo $OUTPUT | $__dirname/json.js Bucket) diff --git a/bin/build.js b/bin/build.js index 89676c1dd..f626f4118 100755 --- a/bin/build.js +++ b/bin/build.js @@ -1,12 +1,12 @@ #! /usr/bin/env node var Promise=require('bluebird') var fs=Promise.promisifyAll(require('fs')) -process.env.AWS_PROFILE=require('../config').profile -process.env.AWS_DEFAULT_REGION=require('../config').profile +process.env.AWS_PROFILE=require('../config.json').profile +process.env.AWS_DEFAULT_REGION=require('../config.json').profile var aws=require('aws-sdk') var chalk=require('chalk') aws.config.setPromisesDependency(Promise) -aws.config.region=require('../config').region +aws.config.region=require('../config.json').region var cf=new aws.CloudFormation() var s3=new aws.S3() var stringify=require("json-stringify-pretty-compact") @@ -48,7 +48,7 @@ async function create(options){ try { var temp=await Promise.resolve(require(file)) var template_string=typeof temp ==="object" ? JSON.stringify(temp) : temp - + log("writing to "+output,!options.silent) await fs.writeFileAsync(output,stringify(JSON.parse(template_string))) diff --git a/bin/check.js b/bin/check.js index 38d1bd658..b8e71d53d 100755 --- a/bin/check.js +++ b/bin/check.js @@ -1,13 +1,13 @@ #! /usr/bin/env node -var config=require('../config') +var config=require('../config.json') var fs=require('fs') process.env.AWS_PROFILE=config.profile process.env.AWS_DEFAULT_REGION=config.profile var aws=require('aws-sdk') var Promise=require('bluebird') aws.config.setPromisesDependency(Promise) -aws.config.region=require('../config').region -var region=require('../config').region +aws.config.region=require('../config.json').region +var region=require('../config.json').region var cf=new aws.CloudFormation() var s3=new aws.S3() var name=require('./name') diff --git a/bin/config.js b/bin/config.js index 968dc0fb5..c38968fff 100644 --- a/bin/config.js +++ b/bin/config.js @@ -17,7 +17,10 @@ module.exports={ "noStackOutput": false, "multiBucketDeployment": false, "buildType": "Custom", - "FulfillmentConcurrency":1 + "FulfillmentConcurrency":1, + "EmbeddingsApi": "SAGEMAKER", + "QASummarizeApi": "SAGEMAKER", + "InstallLexResponseBots": true } if (require.main === module) { diff --git a/bin/exports.js b/bin/exports.js index 7663a0413..ccceaabb5 100755 --- a/bin/exports.js +++ b/bin/exports.js @@ -1,14 +1,14 @@ #! /usr/bin/env node // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -var config=require('../config') +var config=require('../config.json') var fs=require('fs') process.env.AWS_PROFILE=config.profile process.env.AWS_DEFAULT_REGION=config.profile var aws=require('aws-sdk') var Promise=require('bluebird') aws.config.setPromisesDependency(Promise) -aws.config.region=require('../config').region +aws.config.region=require('../config.json').region var name=require('./name') var launch=require('./launch') var _=require('lodash') diff --git a/bin/launch.js b/bin/launch.js index 2412b0f52..14328681a 100755 --- a/bin/launch.js +++ b/bin/launch.js @@ -1,12 +1,12 @@ #! /usr/bin/env node -var config=require('../config') +var config=require('../config.json') process.env.AWS_PROFILE=config.profile process.env.AWS_DEFAULT_REGION=config.profile var aws=require('aws-sdk') var Promise=require('bluebird') aws.config.setPromisesDependency(Promise) -aws.config.region=require('../config').region -var region=require('../config').region +aws.config.region=require('../config.json').region +var region=require('../config.json').region var _=require('lodash') var fs=require('fs') var cf=new aws.CloudFormation() @@ -33,7 +33,7 @@ if (require.main === module) { .option('--no-interactive',"omit interactive elements of output (spinners etc.)") .on('--help',()=>{ log( -` +` Operations: up: launch a stack @@ -184,7 +184,7 @@ function update(stack,options){ }) } - return start.then(x=>{ + return start.then(x=>{ log(`stackname: ${StackName}`,options) log(`stackId: ${x.StackId}`,options) if(options.wait){ @@ -202,7 +202,7 @@ async function down(stack,options){ var StackName=options.stackName ? options.stackName : name(stack) log("terminating stack",options) if(options.dryRun){ - return + return } try{ var down=await cf.describeStacks({ @@ -230,7 +230,7 @@ async function down(stack,options){ async function sure(stack,options={}){ var StackName=options.stackName ? options.stackName : name(stack) log(`making sure stack ${stack} is up`,options) - try{ + try{ await cf.describeStacks({StackName}).promise() await wait(stack,{show:options.interactive && !options.silent}) log(`${stack} is up as ${StackName}`,options) diff --git a/bin/name.js b/bin/name.js index 1fd6305a3..f07e39851 100755 --- a/bin/name.js +++ b/bin/name.js @@ -1,5 +1,5 @@ #! /usr/bin/env node -var config=require('../config') +var config=require('../config.json') var fs=require('fs') var _=require('lodash') process.env.AWS_PROFILE=config.profile @@ -17,7 +17,7 @@ if (require.main === module) { .option('--inc',"increment value") .option('-s --set ',"set the value") .option('-n --namespace ',"stack namespace") - .option('-p --prefix',"get stacks prefix") + .option('-p --prefix',"get stacks prefix") .action(function(stack,options){ if(stack || options.prefix) ran=true console.log(run(stack,options)) @@ -42,7 +42,7 @@ function run(stack,options={}){ var increments={} } } - + var stackname=stack.replace('/','-') var full=`${namespace}-${stackname}` var path=`["${config.profile}"].["${namespace}"].["${stackname}"]` diff --git a/bin/update-public.sh b/bin/update-public.sh index a9d55f561..661f0fea3 100755 --- a/bin/update-public.sh +++ b/bin/update-public.sh @@ -88,10 +88,10 @@ validate_expected_bucket_owner() { parse_arguments $@ __dirname="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -export AWS_PROFILE=$(node -e "console.log(require('$__dirname'+'/../config').profile)") +export AWS_PROFILE=$(node -e "console.log(require('$__dirname'+'/../config.json').profile)") # If profile specified from config file does not exist, allow cli to move on to using instance profile aws configure get aws_access_key_id --profile $AWS_PROFILE || unset AWS_PROFILE -export AWS_DEFAULT_REGION=$(node -e "console.log(require('$__dirname'+'/../config').region)") +export AWS_DEFAULT_REGION=$(node -e "console.log(require('$__dirname'+'/../config.json').region)") OUTPUT=$($__dirname/exports.js dev/bootstrap) DEVBUCKET=$( echo $OUTPUT | $__dirname/json.js Bucket) @@ -100,8 +100,8 @@ REGION=$AWS_DEFAULT_REGION echo $DEVBUCKET -PUBLICBUCKET=$(node -e "console.log(require('$__dirname'+'/../config').publicBucket)") -PUBLICPREFIX=$(node -e "console.log(require('$__dirname'+'/../config').publicPrefix)") +PUBLICBUCKET=$(node -e "console.log(require('$__dirname'+'/../config.json').publicBucket)") +PUBLICPREFIX=$(node -e "console.log(require('$__dirname'+'/../config.json').publicPrefix)") if [[ ${DRY_RUN} -eq 1 || ${RUN} -eq 1 ]]; then validate_expected_bucket_owner $DEVBUCKET $PUBLICBUCKET diff --git a/bin/upload.sh b/bin/upload.sh index 3d6713c8c..07b49d14c 100755 --- a/bin/upload.sh +++ b/bin/upload.sh @@ -74,10 +74,10 @@ validate_expected_bucket_owner() { parse_arguments $@ __dirname="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -export AWS_PROFILE=$(node -e "console.log(require('$__dirname'+'/../config').profile)") +export AWS_PROFILE=$(node -e "console.log(require('$__dirname'+'/../config.json').profile)") # If profile specified from config file does not exist, allow cli to move on to using instance profile aws configure get aws_access_key_id --profile $AWS_PROFILE || unset AWS_PROFILE -export AWS_DEFAULT_REGION=$(node -e "console.log(require('$__dirname'+'/../config').region)") +export AWS_DEFAULT_REGION=$(node -e "console.log(require('$__dirname'+'/../config.json').region)") OUTPUT=$($__dirname/exports.js dev/bootstrap) BUCKET=$( echo $OUTPUT | $__dirname/json.js Bucket) @@ -88,4 +88,4 @@ RESET=$(tput sgr0) echo bootstrap bucket is $BLUE$BUCKET/$PREFIX$RESET validate_expected_bucket_owner $BUCKET -aws s3 sync $__dirname/../build/ s3://$BUCKET/$PREFIX/ --delete +aws s3 sync $__dirname/../build/ s3://$BUCKET/$PREFIX/ --delete diff --git a/bin/wait.js b/bin/wait.js index 4eb1d432a..cefd1fccc 100755 --- a/bin/wait.js +++ b/bin/wait.js @@ -1,10 +1,10 @@ #! /usr/bin/env node var Promise=require('bluebird') -process.env.AWS_PROFILE=require('../config').profile -process.env.AWS_DEFAULT_REGION=require('../config').profile +process.env.AWS_PROFILE=require('../config.json').profile +process.env.AWS_DEFAULT_REGION=require('../config.json').profile var aws=require('aws-sdk') aws.config.setPromisesDependency(Promise) -aws.config.region=require('../config').region +aws.config.region=require('../config.json').region var cf=new aws.CloudFormation() const ora = require('ora'); var name=require('./name') @@ -33,7 +33,7 @@ function wait(stackname,options){ "UPDATE_ROLLBACK_COMPLETE", "DELETE_COMPLETE" ].includes(status)){ - spinner.succeed(StackName+":"+status) + spinner.succeed(StackName+":"+status) res() }else if([ "UPDATE_IN_PROGRESS", diff --git a/deployment/build-s3-dist.sh b/deployment/build-s3-dist.sh index 94cd28cdf..a0311de7d 100755 --- a/deployment/build-s3-dist.sh +++ b/deployment/build-s3-dist.sh @@ -67,12 +67,6 @@ echo "[Init] Install dependencies and build" echo "------------------------------------------------------------------------------" cd $source_dir -# workaround for Config file confusing make and node import of "config.js" -# renaming Config temporarily -if [[ -f "Config" ]]; then - mv Config Config_renamed -fi - npm install npm run configAwsSolutions @@ -83,12 +77,6 @@ do_replace "config.json" %%VERSION%% $version npm run build -# workaround for Config file confusing make and node import of "config.js" -# by renaming back to Config -if [[ -f "Config_renamed" ]]; then - mv Config_renamed Config -fi - echo "------------------------------------------------------------------------------" echo "[Init] Copying templates to global-s3-assets/" echo "------------------------------------------------------------------------------" diff --git a/docs/LLM_Retrieval_and_generative_question_answering/README.md b/docs/LLM_Retrieval_and_generative_question_answering/README.md new file mode 100644 index 000000000..6536d5c1f --- /dev/null +++ b/docs/LLM_Retrieval_and_generative_question_answering/README.md @@ -0,0 +1,181 @@ +# Large Language Model - Query Disambiguation for Conversational Retrieval, and Generative Question Answering + +QnABot can now use a large language model (LLM) to **(1) Disambiguate follow up questions to generate good search queries** and/or **(2) Generate answers to questions from retrieved FAQS or passages**. + + +**(1) Disambiguate follow up questions** that rely on preceding conversation context. The new disambiguated, or standalone, question can then be used as search queries to retrieve the best FAQ, passage or Kendra match. + +Example: + +With the new LLM Disambiguation feature enabled, given the chat history context: +`[{"Human":"Who was Little Bo Peep?"},{"AI":"She is a character from a nursery rhyme who lost her sheep."}]` +and a follow up question: +`Did she find them again?` +QnAbot can rewrite that question to provide all the context required to search for the relevant FAQ or passage: +`Did Little Bo Peep find her sheep again?`. + + +**(2) Generate answers to questions** from context provided by Kendra search results, or from text passges created or imported directly into QnAbot. Some of the benefits include: +- Generated answers allow you to reduce the number of FAQs you need to maintain since you can now synthesize concise answers from your existing documents in a Kendra index, or from document passages stored in QnABot as 'text' items. +- Generated answers can be short, concise, and suitable for voice channel contact center bots as well as website / text bots. +- Generated answers are fully compatible with QnABot's multi-language support - users can interact in their chosen languages and recieve generated answers in the same language. + +Examples: +With the new LLM QA feature enabled, QnABot can answer questions from the [AWS WhitePapers](https://catalog.us-east-1.prod.workshops.aws/workshops/df64824d-abbe-4b0d-8b31-8752bceabade/en-US/200-ingesting-documents/230-using-the-s3-connector/231-ingesting-documents) such as: +- *"What is Dynamo DB?"* -> **Amazon’s Highly Available Key-value Store** + + ![Example1](./images/example_dynamodb.png) + +- *"What frameworks does AWS have to help people design good architectures?"* -> **Well-Architected Framework** + +It can even generate answers to yes/no questions, like: +- *"Is Lambda a database service?"* -> **No, Lambda is not a database service.**. + +If you aren't using AWS Kendra, QnABot can answer questions based on passages created or imported into Content Designer, such as: +- *"Where did Humpty Dumpty sit?"* -> **On the wall**, +- *"Did Humpty Dumpty sit on the wall?"* -> **yes**, +- *"Were the king's horses able to fix Humpty Dumpty?"* -> **No** + +all from a text passage item that contains the nursery rhyme. + +![Example2](./images/example_Humpty_Dumpty.png) + +You can use disambiguation and generative question answering, as shown below: +![Example2](./images/example_disabiguation_and_QA.png) + +**This is an Experimental feature, for now** +- We encourage you to try it on non-production instances to validate accuracy and business value. +- Try different LLM models and APIs +- Experiment with different LLM prompts (easily adjusted using QnABot Settings - discussed below) +- Run throughput testing and inference endpoint scale testing to properly estimate deployment size/costs.. NOTE we do not yet have any scale/costing guidelines, so please share your findings. + + +With this release, you can choose with LLM to use with QnABot: +1. An open source LLM model automtically deployed and hosted on an Amazon SageMaker endpoint - see https://huggingface.co/tiiuae/falcon-40b-instruct +2. Any other LLM model or API you like via a user provided Lambda function. + +_**NOTE: Optimize Kendra:** When using Kendra, we recommend requesting a larger document excerpt to be returned from queries. In the browser window you are using for AWS Management Console navigate to [Kendra Service Quota](https://console.aws.amazon.com/servicequotas/home/services/kendra/quotas/L-196E775D), choose Request quota increase, and change quota value to a number up to a max of 750._ + +### 1. Amazon SAGEMAKER + +QnABot provisions a Sagemaker endpoint running the Hugging Face [tiiuae/falcon-40b-instruct](https://huggingface.co/tiiuae/falcon-40b-instruct) model + +By default a 1-node ml.g5.12xlarge endpoint is automatically provisioned. For large volume deployments, add additional nodes by setting the parameter `LLMSagemakerInitialInstanceCount`. Please check [SageMaker pricing documentation](https://aws.amazon.com/sagemaker/pricing/) for relevant costs and information on Free Tier eligibility. + +#### Deploy Stack for SAGEMAKER + +- *(for Kendra Fallback)* set `DefaultKendraIndexId` to the Index Id (a GUID) of your existing Kendra index containing ingested documents +- *(for text passage queries)* set `EmbeddingsApi` to SAGEMAKER or LAMBDA (see [Semantic Search using Text Embeddings](../semantic_matching_using_LLM_embeddings/README.md)) +- set `LLMApi` to SAGEMAKER + +![CFN Params](./images/CF_Params_SageMaker.png) + +### 2. Lambda function + +Use a custom Lambda function to experiment with LLMs of your choice. Provide your own lambda function that takes a *question*, *context*, and a QnABot *settings* object. Your Lambda function can invoke any LLM you choose, and return the prediction in a JSON object containing the key, `generated_text`. You provide the ARN for your Lambda function when you deploy or update QnABot. + +#### Deploy Stack for Embedding models invoked by a custom Lambda Function + +- *(for Kendra Fallback)* set `DefaultKendraIndexId` to the Index Id (a GUID) of your existing Kendra index containing ingested documents +- *(for text passage queries)* set `EmbeddingsApi` to SAGEMAKER or LAMBDA (see [Semantic Search using Text Embeddings](../semantic_matching_using_LLM_embeddings/README.md)) +- set `LLMApi` to LAMBDA +- set `LLMLambdaArn` to the ARN of your Lambda function + +![CFN Params](./images/CF_Params_Lambda.png) + +Your Lambda function is passed an event of the form: +``` +{ + "prompt": "string", // prompt for the LLM + "parameters":{"temperature":0,...}, // model parameters object containing key / value pairs for the model parameters setting (defined in QnABot settings - see below) + "settings":{"key1":"value1",...} // settings object containing all default and custom QnAbot settings +} +``` +and returns a JSON structure of the form: +``` +{"generated_text":"string"} +``` + +Here's an example of a minimal Lambda function for testing. Of course you need to extend it to actually invoke your LLM! +``` +def lambda_handler(event, context): + print(event) + prompt = event["prompt"] + model_params = event["parameters"] + settings = event["settings"] + generated_text = f"This is the prompt: {prompt}" # REPLACE WITH LLM INFERENCE API CALL + return { + 'generated_text': generated_text + } +``` + + +### Relevant Settings + +When QnABot stack is installed, open Content Designer **Settings** page: + +- **ENABLE_DEBUG_RESPONSES** set to TRUE to add additional debug information to the QnABot response, including any language translations (if using multi language mode), question disambiguation (before and after), and inference times for your LLM model(s). + +- **ES_SCORE_TEXT_ITEM_PASSAGES:** should be "true" to enable the new QnABot text passage items to be retrieved and used as input context for geneartive QA Summary answers. NOTE - 'qna' items are queried first, and in none meet the score threshold, then QnABot queries the text field of 'text' items + +- **EMBEDDINGS_TEXT_PASSAGE_SCORE_THRESHOLD:** applies only when Embeddings are enabled (recommended) and if ES_SCORE_TEXT_ITEM_PASSAGES is true. If embedding similarity score on text item field is under threshold the match is rejected. Default is 0.80. + +- **ALT_SEARCH_KENDRA_INDEXES:** be set to the Id (not the name) of your Kendra index where you have ingested documents of web pages that you want to use as source passages for generative answers. If you plan to use only QnABot text passage items instead of Kendra, leave this setting blank. + +- **ALT_SEARCH_KENDRA_MAX_DOCUMENT_COUNT:** the number of passages from Kendra to provide in the input context for the LLM. + +*Scroll to the bottom of the settings page and observe the new LLM settings:* + +- **LLM_API:** one of SAGEMAKER, LAMBDA - based on the value chosen when you last deployed or updated the QnABot Stack. +- **LLM_GENERATE_QUERY_ENABLE:** set to TRUE or FALSE to enable or disable question disambiguation. +- **LLM_GENERATE_QUERY_PROMPT_TEMPLATE:** the prompt template used to construct a prompt for the LLM to disabiguate a followup question. The template may use the placeholders: + - `{history}` - placeholder for the last `LLM_CHAT_HISTORY_MAX_MESSAGES` messages in the conversational history, to provide conversational context. + - `{input}` - placeholder for the current user utterance / question +- **LLM_GENERATE_QUERY_MODEL_PARAMS:** parameters sent to the LLM model when disambiguating follow-up questions. Default: `{"temperature":0}`. Check model documentation for additional values that your model provider accepts. +- **LLM_QA_ENABLE:** set to TRUE or FALSE to enable or disable generative answers from passages retreived via embeddings or Kendra fallback (when no FAQ match its found). NOTE LLM based generative answers are not applied when an FAQ / QID matches the question. +- **LLM_QA_USE_KENDRA_RETRIEVAL_API:** set to TRUE or FALSE to enable or disable the use of Kendra's retrieval API. When enabled, QnABot uses Kendra's Retrieve api to retrieve semantically relevant passages of up to 200 token words from the documents in your index (not FAQs). When disabled, QnAbot use the default Kendra Query API to search documents and FAQs. Takes effect only when LLM_QA_ENABLE is TRUE. The default is TRUE (recommended) when LLM QA is enabled. Note: this feature will only search the first configured index. See https://docs.aws.amazon.com/kendra/latest/APIReference/API_Retrieve.html +- **LLM_QA_PROMPT_TEMPLATE:** the prompt template used to construct a prompt for the LLM to generate an answer from the context of a retrieved passages (from Kendra or Embeddings). The template may use the placeholders: + - `{context}` - placeholder for passages retrieved from the seartch query - either a QnABot 'Text' item passage, or the Top `ALT_SEARCH_KENDRA_MAX_DOCUMENT_COUNT` Kendra passages + - `{history}` - placeholder for the last `LLM_CHAT_HISTORY_MAX_MESSAGES` messages in the conversational history, to provide conversational context. + - `{input}` - placeholder for the current user utterance / question + - `{query}` - placeholder for the generated (disambiguated) query created by the generate query feature. NOTE the default prompt does not use `query` in the qa prompt, as it provides the conversation history and current user input instead, but you can change the prompt to use `query` inseatd of, or in addiotion to `input` and `history` to tune the LLM answers. +- **LLM_QA_NO_HITS_REGEX:** when the pattern specified matches the response from the LLM, e.g. `Sorry, I don't know`, then the response is treated as no_hits, and the default `EMPTYMESSAGE` or Custom Don't Know ('no_hits') item is returned instead. Disabled by default, since enabling it prevents easy debugging of LLM don't know responses. +- **LLM_QA_MODEL_PARAMS:** parameters sent to the LLM model when generating answers to questions. Default: `{"temperature":0}`. Check model documentation for additional values that your model provider accepts. +- **LLM_QA_PREFIX_MESSAGE:** Message use to prefix LLM generated answer. May be be empty. +- **LLM_QA_SHOW_CONTEXT_TEXT:** set to TRUE or FALSE to enable or disable inclusion of the passages (from Kendra or Embeddings) used as context for LLM generated answers. +- **LLM_QA_SHOW_SOURCE_LINKS:** set to TRUE or FALSE to enable or disable Kendra Source Links or passage refMarkdown links (doc references) in markdown answers. +- **LLM_CHAT_HISTORY_MAX_MESSAGES:** the number of previous questions and answers (chat history) to maintain (in the QnABot DynamoDB UserTable). Chat History is necessary for QnABot to disambiguate follow up questions from previous question and answer context. + + +## Try it! + +**With Kendra** + +Use it with your Kendra index to ask questions that can be answered from web pages that you've crawled or documents that you've ingested using a Kendra data source connector. If you're not sure how to load documents into Kendra, see the Kendra Essentials Workshop: [Ingesting AWS WhitePapers into a Kendra index](https://catalog.us-east-1.prod.workshops.aws/workshops/df64824d-abbe-4b0d-8b31-8752bceabade/en-US/200-ingesting-documents/230-using-the-s3-connector/231-ingesting-documents) + + +**With the new Text item type** + +Use the new **QnABot Text item** to directly create your own passages of text in QnABot's embedded OpenSearch store. +In Content Designer, choose **Add**, select **text**, enter an Item ID and a Passage, and choose **Create**. + +![CFN Params](./images/TextItem_JackHorner.png) + +QnABot saves your passage, along with the text embeddings; for best results when using native passage retrieval in QnABot, be sure to enable [Semantic Search using Text Embeddings](../semantic_matching_using_LLM_embeddings/README.md). + +Test your queries match the desired text item using the TEST tab in Content Designer. To test matches for text item passages, select the appropriate drop down before choosing SEARCH. Compare scores on "qna questions" to the configured threshold setting `EMBEDDINGS_SCORE_THTRESHOLD` and for passages to the threshold setting `EMBEDDINGS_TEXT_PASSAGE_SCORE_THRESHOLD`. You may need to adjust thresholds to get the desired behavior when using the bot with the web client. + +You can also import your passages from a JSON file using Content Designer import. From the Tools menu on the top left, choose **Import**, open **Examples/Extensions** and choose the LOAD button next to **TextPassage-NurseryRhymeExamples** to import two nursery rhyme text items. +To import your own passages create and import a JSON file with the structure similar to below: +``` +{ + "qna": [ + { + "passage": "Humpty Dumpty sat on the wall,\nHumpty Dumpty had a great fall,\nAll the king's horses and all the king's men,\nCouldn't put Humpty together again.", + "type": "text", + "qid": "0.HumptyDumpty" + } + ] +} +``` + diff --git a/docs/LLM_Retrieval_and_generative_question_answering/images/CF_Params_Lambda.png b/docs/LLM_Retrieval_and_generative_question_answering/images/CF_Params_Lambda.png new file mode 100644 index 000000000..6c4dba0b3 Binary files /dev/null and b/docs/LLM_Retrieval_and_generative_question_answering/images/CF_Params_Lambda.png differ diff --git a/docs/LLM_Retrieval_and_generative_question_answering/images/CF_Params_SageMaker.png b/docs/LLM_Retrieval_and_generative_question_answering/images/CF_Params_SageMaker.png new file mode 100644 index 000000000..b786b9e7c Binary files /dev/null and b/docs/LLM_Retrieval_and_generative_question_answering/images/CF_Params_SageMaker.png differ diff --git a/docs/LLM_Retrieval_and_generative_question_answering/images/TextItem_JackHorner.png b/docs/LLM_Retrieval_and_generative_question_answering/images/TextItem_JackHorner.png new file mode 100644 index 000000000..ab0867245 Binary files /dev/null and b/docs/LLM_Retrieval_and_generative_question_answering/images/TextItem_JackHorner.png differ diff --git a/docs/LLM_Retrieval_and_generative_question_answering/images/example_Humpty_Dumpty.png b/docs/LLM_Retrieval_and_generative_question_answering/images/example_Humpty_Dumpty.png new file mode 100644 index 000000000..03b574cf8 Binary files /dev/null and b/docs/LLM_Retrieval_and_generative_question_answering/images/example_Humpty_Dumpty.png differ diff --git a/docs/LLM_Retrieval_and_generative_question_answering/images/example_disabiguation_and_QA.png b/docs/LLM_Retrieval_and_generative_question_answering/images/example_disabiguation_and_QA.png new file mode 100644 index 000000000..fcf84aa86 Binary files /dev/null and b/docs/LLM_Retrieval_and_generative_question_answering/images/example_disabiguation_and_QA.png differ diff --git a/docs/LLM_Retrieval_and_generative_question_answering/images/example_dynamodb.png b/docs/LLM_Retrieval_and_generative_question_answering/images/example_dynamodb.png new file mode 100644 index 000000000..530d7a61f Binary files /dev/null and b/docs/LLM_Retrieval_and_generative_question_answering/images/example_dynamodb.png differ diff --git a/docs/architecture.png b/docs/architecture.png index 941662a00..de394badc 100644 Binary files a/docs/architecture.png and b/docs/architecture.png differ diff --git a/docs/architecture.xml b/docs/architecture.xml index a4e2f3d88..145d729a3 100644 --- a/docs/architecture.xml +++ b/docs/architecture.xml @@ -1 +1 @@ -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 \ No newline at end of file +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 \ No newline at end of file diff --git a/lambda/aws-sdk-layer/package-lock.json b/lambda/aws-sdk-layer/package-lock.json index 6e79b7fca..b77e37f8d 100644 --- a/lambda/aws-sdk-layer/package-lock.json +++ b/lambda/aws-sdk-layer/package-lock.json @@ -7,9 +7,9 @@ "": { "name": "aws-layer", "version": "1.0.0", - "license": "ISC", + "license": "Apache-2.0", "dependencies": { - "aws-sdk": "^2.1354.0", + "aws-sdk": "^2.1404.0", "http-aws-es": "^6.0.0" } }, @@ -55,9 +55,9 @@ } }, "node_modules/aws-sdk": { - "version": "2.1354.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1354.0.tgz", - "integrity": "sha512-3aDxvyuOqMB9DqJguCq6p8momdsz0JR1axwkWOOCzHA7a35+Bw+WLmqt3pWwRjR1tGIwkkZ2CvGJObYHsOuw3w==", + "version": "2.1404.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1404.0.tgz", + "integrity": "sha512-pt8SXXH/CDwA0qTNV1SkHhLXnIb9fk1NTutE5w/tj9u8Z5DSbHbc9bnmju1B9aoRG1VTR48/SqOyzkfquVnMCw==", "dependencies": { "buffer": "4.9.2", "events": "1.1.1", @@ -494,9 +494,9 @@ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" }, "aws-sdk": { - "version": "2.1354.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1354.0.tgz", - "integrity": "sha512-3aDxvyuOqMB9DqJguCq6p8momdsz0JR1axwkWOOCzHA7a35+Bw+WLmqt3pWwRjR1tGIwkkZ2CvGJObYHsOuw3w==", + "version": "2.1404.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1404.0.tgz", + "integrity": "sha512-pt8SXXH/CDwA0qTNV1SkHhLXnIb9fk1NTutE5w/tj9u8Z5DSbHbc9bnmju1B9aoRG1VTR48/SqOyzkfquVnMCw==", "requires": { "buffer": "4.9.2", "events": "1.1.1", diff --git a/lambda/aws-sdk-layer/package.json b/lambda/aws-sdk-layer/package.json index e66e2127f..d8274fd52 100644 --- a/lambda/aws-sdk-layer/package.json +++ b/lambda/aws-sdk-layer/package.json @@ -6,10 +6,13 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, - "author": "", - "license": "ISC", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com/solutions" + }, + "license": "Apache-2.0", "dependencies": { - "aws-sdk": "^2.1354.0", + "aws-sdk": "^2.1404.0", "http-aws-es": "^6.0.0" } } diff --git a/lambda/cfn-lambda-layer/package-lock.json b/lambda/cfn-lambda-layer/package-lock.json index 2dd6da934..d44a031bc 100644 --- a/lambda/cfn-lambda-layer/package-lock.json +++ b/lambda/cfn-lambda-layer/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "cfn-lambda-layer", "version": "1.0.0", - "license": "ISC", + "license": "Apache-2.0", "dependencies": { "cfn-lambda": "^5.1.0" } diff --git a/lambda/cfn-lambda-layer/package.json b/lambda/cfn-lambda-layer/package.json index 98f45f9d0..9f2b45d15 100644 --- a/lambda/cfn-lambda-layer/package.json +++ b/lambda/cfn-lambda-layer/package.json @@ -6,8 +6,11 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, - "author": "", - "license": "ISC", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com/solutions" + }, + "license": "Apache-2.0", "dependencies": { "cfn-lambda": "^5.1.0" }, diff --git a/lambda/cfn/lib/S3Lambda.js b/lambda/cfn/lib/S3Lambda.js index bec5298fb..0971257dd 100644 --- a/lambda/cfn/lib/S3Lambda.js +++ b/lambda/cfn/lib/S3Lambda.js @@ -1,6 +1,5 @@ var aws=require('./util/aws') var Promise=require('./util/promise') -var cfnLambda=require('cfn-lambda') var base=require('./base.js') var s3=new aws.S3() @@ -8,7 +7,7 @@ module.exports=class S3Lambda extends base{ constructor(){ super('BucketNotificationConfiguration') } - + Create(params,reply){ var that=this Promise.retry( diff --git a/lambda/cfn/lib/lex.js b/lambda/cfn/lib/lex.js index 12d654581..2d0c46ed7 100644 --- a/lambda/cfn/lib/lex.js +++ b/lambda/cfn/lib/lex.js @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 var aws=require('aws-sdk') -var cfnLambda=require('cfn-lambda') var Promise=require('bluebird') aws.config.region=process.env.REGION aws.config.setPromisesDependency(Promise) @@ -514,12 +513,12 @@ class Lex { reply(null,ID) } } - + Delete(ID,params,reply){ var arg={name:ID} if(this.type==="BotAlias") arg.botName=params.botName - + return run(this.delete_method,arg) .then(msg=>reply(null,msg.name,null)) .catch(function(error){ diff --git a/lambda/cfn/package-lock.json b/lambda/cfn/package-lock.json index 964aca5e8..bff348f54 100644 --- a/lambda/cfn/package-lock.json +++ b/lambda/cfn/package-lock.json @@ -7,51 +7,14 @@ "": { "name": "cfn", "version": "1.0.0", - "license": "ISC", + "license": "Apache-2.0", "dependencies": { - "aws-sdk": "^2.1354.0", + "aws-sdk": "^2.1404.0", "bluebird": "^3.5.0", "body-parser": "^1.19.2", - "cfn-lambda": "^4.0.0", - "cfn-response": "^1.0.1", - "deep-equal": "^1.0.1", - "elasticsearch": "^16.7.1", - "http-aws-es": "^6.0.0", - "intercept-stdout": "^0.1.2", - "json-stringify-pretty-compact": "^1.0.4", + "cfn-lambda": "^5.1.0", "jszip": "^3.10.1", - "lodash": "^4.17.21", - "stack-utils": "^1.0.1" - }, - "devDependencies": { - "diff": "^4.0.2" - } - }, - "node_modules/agentkeepalive": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz", - "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==", - "dependencies": { - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "engines": { - "node": ">=0.10.0" + "lodash": "^4.17.21" } }, "node_modules/archiver": { @@ -130,9 +93,9 @@ } }, "node_modules/aws-sdk": { - "version": "2.1354.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1354.0.tgz", - "integrity": "sha512-3aDxvyuOqMB9DqJguCq6p8momdsz0JR1axwkWOOCzHA7a35+Bw+WLmqt3pWwRjR1tGIwkkZ2CvGJObYHsOuw3w==", + "version": "2.1404.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1404.0.tgz", + "integrity": "sha512-pt8SXXH/CDwA0qTNV1SkHhLXnIb9fk1NTutE5w/tj9u8Z5DSbHbc9bnmju1B9aoRG1VTR48/SqOyzkfquVnMCw==", "dependencies": { "buffer": "4.9.2", "events": "1.1.1", @@ -262,36 +225,16 @@ } }, "node_modules/cfn-lambda": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cfn-lambda/-/cfn-lambda-4.0.0.tgz", - "integrity": "sha512-eM8YjA5MHlFFjYd+GdmZF3CcsXJ7qUDKBr99r0qpaHp2fTAH8nVlSDWhFPwfjQJpAyPAlrKMbn63ofYj8SfCrA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cfn-lambda/-/cfn-lambda-5.1.0.tgz", + "integrity": "sha512-kWSf43HeB27UsfMJ7pEJWJHCql/pR/qlg3m7rPZUwG4Hr+YWAcSHlW9/Bb7rtNv2BJ6unjmFJO9iBkAtCgUWhQ==", "dependencies": { - "archiver": "^3.0.0", + "archiver": "^3.1.1", "async": "^1.5.2", - "aws-sdk": "^2.417.0", - "jsonschema": "^1.2.4", + "aws-sdk": "^2.853.0", + "jsonschema": "^1.4.0", "nano-argv": "^1.0.2", - "underscore": "^1.8.3" - } - }, - "node_modules/cfn-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cfn-response/-/cfn-response-1.0.1.tgz", - "integrity": "sha1-qOwDlQwGg8UUlejKaA2dwLiEsTc=" - }, - "node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" + "underscore": "^1.12.0" } }, "node_modules/compress-commons": { @@ -369,30 +312,6 @@ "node": ">= 6.9.0" } }, - "node_modules/deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "dependencies": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dependencies": { - "object-keys": "^1.0.12" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -410,33 +329,11 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, - "node_modules/elasticsearch": { - "version": "16.7.1", - "resolved": "https://registry.npmjs.org/elasticsearch/-/elasticsearch-16.7.1.tgz", - "integrity": "sha512-PL/BxB03VGbbghJwISYvVcrR9KbSSkuQ7OM//jHJg/End/uC2fvXg4QI7RXLvCGbhBuNQ8dPue7DOOPra73PCw==", - "dependencies": { - "agentkeepalive": "^3.4.1", - "chalk": "^1.0.0", - "lodash": "^4.17.10" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -445,48 +342,6 @@ "once": "^1.4.0" } }, - "node_modules/es-abstract": { - "version": "1.17.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", - "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", - "dependencies": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/events": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", @@ -574,17 +429,6 @@ "node": ">= 0.4.0" } }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -610,11 +454,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/http-aws-es": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/http-aws-es/-/http-aws-es-6.0.0.tgz", - "integrity": "sha512-g+qp7J110/m4aHrR3iit4akAlnW0UljZ6oTq/rCcbsI8KP9x+95vqUtx49M2XQ2JMpwJio3B6gDYx+E8WDxqiA==" - }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -630,14 +469,6 @@ "node": ">= 0.8" } }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", - "dependencies": { - "ms": "^2.0.0" - } - }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -673,14 +504,6 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "node_modules/intercept-stdout": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/intercept-stdout/-/intercept-stdout-0.1.2.tgz", - "integrity": "sha1-Emq/H65sUJpCipjGGmMVWQQq6f0=", - "dependencies": { - "lodash.toarray": "^3.0.0" - } - }, "node_modules/is-arguments": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", @@ -697,14 +520,6 @@ "node": ">= 0.4" } }, - "node_modules/is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/is-generator-function": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", @@ -719,28 +534,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", - "dependencies": { - "has": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dependencies": { - "has-symbols": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/is-typed-array": { "version": "1.1.10", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", @@ -772,15 +565,10 @@ "node": ">= 0.6.0" } }, - "node_modules/json-stringify-pretty-compact": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-1.2.0.tgz", - "integrity": "sha512-/11Pj1OyX814QMKO7K8l85SHPTr/KsFxHp8GE2zVa0BtJgGimDjXHfM3FhC7keQdWDea7+nXf+f1de7ATZcZkQ==" - }, "node_modules/jsonschema": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.2.6.tgz", - "integrity": "sha512-SqhURKZG07JyKKeo/ir24QnS4/BV7a6gQy93bUSe4lUdNp0QNpIz2c9elWJQ9dpc5cQYY6cvCzgRwy0MQCLyqA==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", + "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", "engines": { "node": "*" } @@ -848,21 +636,6 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "node_modules/lodash._arraycopy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz", - "integrity": "sha1-due3wfH7klRzdIeKVi7Qaj5Q9uE=" - }, - "node_modules/lodash._basevalues": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", - "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=" - }, - "node_modules/lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" - }, "node_modules/lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -878,41 +651,11 @@ "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" }, - "node_modules/lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" - }, - "node_modules/lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" - }, "node_modules/lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" }, - "node_modules/lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "dependencies": { - "lodash._getnative": "^3.0.0", - "lodash.isarguments": "^3.0.0", - "lodash.isarray": "^3.0.0" - } - }, - "node_modules/lodash.toarray": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-3.0.2.tgz", - "integrity": "sha1-KyBPD6T1HChcbwDIHRzqWiMEEXk=", - "dependencies": { - "lodash._arraycopy": "^3.0.0", - "lodash._basevalues": "^3.0.0", - "lodash.keys": "^3.0.0" - } - }, "node_modules/lodash.union": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", @@ -982,40 +725,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-is": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", - "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dependencies": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -1107,18 +816,6 @@ "node": ">= 6" } }, - "node_modules/regexp.prototype.flags": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", - "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -1157,14 +854,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -1181,69 +870,6 @@ "safe-buffer": "~5.1.0" } }, - "node_modules/string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "node_modules/string.prototype.trimleft": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", - "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimstart": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/string.prototype.trimright": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", - "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimend": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/tar-stream": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", @@ -1382,24 +1008,6 @@ } }, "dependencies": { - "agentkeepalive": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz", - "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==", - "requires": { - "humanize-ms": "^1.2.1" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, "archiver": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", @@ -1468,9 +1076,9 @@ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" }, "aws-sdk": { - "version": "2.1354.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1354.0.tgz", - "integrity": "sha512-3aDxvyuOqMB9DqJguCq6p8momdsz0JR1axwkWOOCzHA7a35+Bw+WLmqt3pWwRjR1tGIwkkZ2CvGJObYHsOuw3w==", + "version": "2.1404.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1404.0.tgz", + "integrity": "sha512-pt8SXXH/CDwA0qTNV1SkHhLXnIb9fk1NTutE5w/tj9u8Z5DSbHbc9bnmju1B9aoRG1VTR48/SqOyzkfquVnMCw==", "requires": { "buffer": "4.9.2", "events": "1.1.1", @@ -1588,33 +1196,16 @@ } }, "cfn-lambda": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cfn-lambda/-/cfn-lambda-4.0.0.tgz", - "integrity": "sha512-eM8YjA5MHlFFjYd+GdmZF3CcsXJ7qUDKBr99r0qpaHp2fTAH8nVlSDWhFPwfjQJpAyPAlrKMbn63ofYj8SfCrA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cfn-lambda/-/cfn-lambda-5.1.0.tgz", + "integrity": "sha512-kWSf43HeB27UsfMJ7pEJWJHCql/pR/qlg3m7rPZUwG4Hr+YWAcSHlW9/Bb7rtNv2BJ6unjmFJO9iBkAtCgUWhQ==", "requires": { - "archiver": "^3.0.0", + "archiver": "^3.1.1", "async": "^1.5.2", - "aws-sdk": "^2.417.0", - "jsonschema": "^1.2.4", + "aws-sdk": "^2.853.0", + "jsonschema": "^1.4.0", "nano-argv": "^1.0.2", - "underscore": "^1.8.3" - } - }, - "cfn-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cfn-response/-/cfn-response-1.0.1.tgz", - "integrity": "sha1-qOwDlQwGg8UUlejKaA2dwLiEsTc=" - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "underscore": "^1.12.0" } }, "compress-commons": { @@ -1687,27 +1278,6 @@ "readable-stream": "^3.4.0" } }, - "deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -1718,27 +1288,11 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, - "elasticsearch": { - "version": "16.7.1", - "resolved": "https://registry.npmjs.org/elasticsearch/-/elasticsearch-16.7.1.tgz", - "integrity": "sha512-PL/BxB03VGbbghJwISYvVcrR9KbSSkuQ7OM//jHJg/End/uC2fvXg4QI7RXLvCGbhBuNQ8dPue7DOOPra73PCw==", - "requires": { - "agentkeepalive": "^3.4.1", - "chalk": "^1.0.0", - "lodash": "^4.17.10" - } - }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -1747,39 +1301,6 @@ "once": "^1.4.0" } }, - "es-abstract": { - "version": "1.17.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", - "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, "events": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", @@ -1852,14 +1373,6 @@ "function-bind": "^1.1.1" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -1873,11 +1386,6 @@ "has-symbols": "^1.0.2" } }, - "http-aws-es": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/http-aws-es/-/http-aws-es-6.0.0.tgz", - "integrity": "sha512-g+qp7J110/m4aHrR3iit4akAlnW0UljZ6oTq/rCcbsI8KP9x+95vqUtx49M2XQ2JMpwJio3B6gDYx+E8WDxqiA==" - }, "http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -1890,14 +1398,6 @@ "toidentifier": "1.0.1" } }, - "humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", - "requires": { - "ms": "^2.0.0" - } - }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -1930,14 +1430,6 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "intercept-stdout": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/intercept-stdout/-/intercept-stdout-0.1.2.tgz", - "integrity": "sha1-Emq/H65sUJpCipjGGmMVWQQq6f0=", - "requires": { - "lodash.toarray": "^3.0.0" - } - }, "is-arguments": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", @@ -1948,11 +1440,6 @@ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==" }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" - }, "is-generator-function": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", @@ -1961,22 +1448,6 @@ "has-tostringtag": "^1.0.0" } }, - "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", - "requires": { - "has": "^1.0.3" - } - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "requires": { - "has-symbols": "^1.0.1" - } - }, "is-typed-array": { "version": "1.1.10", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", @@ -1999,15 +1470,10 @@ "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==" }, - "json-stringify-pretty-compact": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-1.2.0.tgz", - "integrity": "sha512-/11Pj1OyX814QMKO7K8l85SHPTr/KsFxHp8GE2zVa0BtJgGimDjXHfM3FhC7keQdWDea7+nXf+f1de7ATZcZkQ==" - }, "jsonschema": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.2.6.tgz", - "integrity": "sha512-SqhURKZG07JyKKeo/ir24QnS4/BV7a6gQy93bUSe4lUdNp0QNpIz2c9elWJQ9dpc5cQYY6cvCzgRwy0MQCLyqA==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", + "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==" }, "jszip": { "version": "3.10.1", @@ -2073,21 +1539,6 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "lodash._arraycopy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz", - "integrity": "sha1-due3wfH7klRzdIeKVi7Qaj5Q9uE=" - }, - "lodash._basevalues": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", - "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=" - }, - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" - }, "lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -2103,41 +1554,11 @@ "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" - }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" - }, "lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "requires": { - "lodash._getnative": "^3.0.0", - "lodash.isarguments": "^3.0.0", - "lodash.isarray": "^3.0.0" - } - }, - "lodash.toarray": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-3.0.2.tgz", - "integrity": "sha1-KyBPD6T1HChcbwDIHRzqWiMEEXk=", - "requires": { - "lodash._arraycopy": "^3.0.0", - "lodash._basevalues": "^3.0.0", - "lodash.keys": "^3.0.0" - } - }, "lodash.union": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", @@ -2189,31 +1610,6 @@ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" }, - "object-is": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", - "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, "on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -2284,15 +1680,6 @@ "util-deprecate": "^1.0.1" } }, - "regexp.prototype.flags": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", - "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -2328,11 +1715,6 @@ "object-inspect": "^1.9.0" } }, - "stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==" - }, "statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -2346,57 +1728,6 @@ "safe-buffer": "~5.1.0" } }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimleft": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", - "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimstart": "^1.0.0" - } - }, - "string.prototype.trimright": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", - "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimend": "^1.0.0" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - }, "tar-stream": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", diff --git a/lambda/cfn/package.json b/lambda/cfn/package.json index 44aa92039..4fcd849cb 100644 --- a/lambda/cfn/package.json +++ b/lambda/cfn/package.json @@ -7,27 +7,20 @@ "test": "nodeunit ./test/index.js", "unit": "nodeunit ./test/index.js -t" }, - "author": "", - "license": "ISC", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com/solutions" + }, + "license": "Apache-2.0", "dependencies": { - "aws-sdk": "^2.1354.0", + "aws-sdk": "^2.1404.0", "bluebird": "^3.5.0", "body-parser": "^1.19.2", - "cfn-lambda": "^4.0.0", - "cfn-response": "^1.0.1", - "deep-equal": "^1.0.1", - "elasticsearch": "^16.7.1", - "http-aws-es": "^6.0.0", - "intercept-stdout": "^0.1.2", - "json-stringify-pretty-compact": "^1.0.4", + "cfn-lambda": "^5.1.0", "jszip": "^3.10.1", - "lodash": "^4.17.21", - "stack-utils": "^1.0.1" - }, - "devDependencies": { - "diff": "^4.0.2" + "lodash": "^4.17.21" }, "overrides": { "qs@<6.5.3": "^6.5.3" } -} \ No newline at end of file +} diff --git a/lambda/cfn/test/lex.js b/lambda/cfn/test/lex.js index 0f51f4469..37c9bc837 100644 --- a/lambda/cfn/test/lex.js +++ b/lambda/cfn/test/lex.js @@ -1,7 +1,7 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -process.env.REGION=require('../../../config').region +process.env.REGION=require('../../../config.json').region var lex=require('../lib/lex') var Promise=require('bluebird') diff --git a/lambda/cfn/test/params/base.js b/lambda/cfn/test/params/base.js index d68cc5306..1b9183cd3 100644 --- a/lambda/cfn/test/params/base.js +++ b/lambda/cfn/test/params/base.js @@ -1,4 +1,4 @@ -var config=require('../../../../config') +var config=require('../../../../config.json') process.env.AWS_REGION=config.region module.exports=function(type,stage,properties){ diff --git a/lambda/cfn/test/setup.js b/lambda/cfn/test/setup.js index 94d87fb53..33bba2b68 100755 --- a/lambda/cfn/test/setup.js +++ b/lambda/cfn/test/setup.js @@ -1,7 +1,7 @@ #! /usr/bin/env node process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; var Promise=require('bluebird') -var config=require('../../../config') +var config=require('../../../config.json') var outputs=require('../../../bin/exports') var fs=Promise.promisifyAll(require('fs')) @@ -14,10 +14,10 @@ module.exports=function(event){ process.env.AWS_SECRET_ACCESS_KEY=aws.config.credentials.secretAccessKey process.env.AWS_REGION=config.region - + return Promise.join( event, - outputs('dev/lambda') + outputs('dev/lambda') ).spread(function(ev,output){ return new Promise(function(res,rej){ require('../index.js').handler(ev,{ diff --git a/lambda/common-modules-layer/package-lock.json b/lambda/common-modules-layer/package-lock.json index 163fd29b9..6cdeb8a9a 100644 --- a/lambda/common-modules-layer/package-lock.json +++ b/lambda/common-modules-layer/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "common-modules-layer", "version": "1.0.0", - "license": "ISC", + "license": "Apache-2.0", "dependencies": { "bluebird": "^3.7.2", "bodybuilder": "^2.4.0", diff --git a/lambda/common-modules-layer/package.json b/lambda/common-modules-layer/package.json index 1460acfb8..d478dcd2b 100644 --- a/lambda/common-modules-layer/package.json +++ b/lambda/common-modules-layer/package.json @@ -13,6 +13,9 @@ "intercept-stdout": "^0.1.2", "lodash": "^4.17.21" }, - "author": "", - "license": "ISC" + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com/solutions" + }, + "license": "Apache-2.0" } diff --git a/lambda/connect/package-lock.json b/lambda/connect/package-lock.json index 3f76724f2..3a2aa6edf 100644 --- a/lambda/connect/package-lock.json +++ b/lambda/connect/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "connect", "version": "1.0.0", - "license": "SEE LICENSE IN LICENSE", + "license": "Apache-2.0", "devDependencies": { "jest": "^29.4.3" } diff --git a/lambda/connect/package.json b/lambda/connect/package.json index 3a25c6742..3dbe0bd41 100644 --- a/lambda/connect/package.json +++ b/lambda/connect/package.json @@ -19,7 +19,7 @@ "name": "Amazon Web Services", "url": "https://aws.amazon.com/solutions" }, - "license": "SEE LICENSE IN LICENSE", + "license": "Apache-2.0", "devDependencies": { "jest": "^29.4.3" } diff --git a/lambda/es-proxy-layer/lib/es_query.js b/lambda/es-proxy-layer/lib/es_query.js index be3f88481..da105afb6 100644 --- a/lambda/es-proxy-layer/lib/es_query.js +++ b/lambda/es-proxy-layer/lib/es_query.js @@ -94,13 +94,13 @@ async function run_query_es(req, query_params) { if ( !gothits && _.get(query_params, 'settings.ES_SCORE_ANSWER_FIELD')) { qnabot.log("ES_SCORE_ANSWER_FIELD is true. Rerun query to check for matches on answer field.") query_params.score_answer = true; - let es_query_an_answer = await build_es_query(query_params); + let es_query_on_answer = await build_es_query(query_params); es_response = await request({ url: `https://${req._info.es.address}/${req._info.es.index}/_search?search_type=dfs_query_then_fetch`, method: "GET", - body: es_query_an_answer + body: es_query_on_answer }); - // check threshold - always '1' is not using embeddings + // check threshold - always '1' if not using embeddings let threshold = (_.get(query_params, 'settings.EMBEDDINGS_ENABLE')) ? _.get(query_params,'settings.EMBEDDINGS_SCORE_ANSWER_THRESHOLD',0) : 1 qnabot.log(`Score threshold for answer matches is: ${threshold}.`) es_response = score_threshold_check(es_response, threshold) @@ -108,6 +108,25 @@ async function run_query_es(req, query_params) { matched_field = (gothits) ? "answer" : ""; } + // if EMBEDDINGS_ENABLE_TEXT_PASSAGE_QUERIES is true, AND no hits were returned from previous query(s), run + // another query to match the item text passage field (applicable on for items of type 'text'). + if ( !gothits && _.get(query_params, 'settings.ES_SCORE_TEXT_ITEM_PASSAGES')) { + qnabot.log("ES_SCORE_TEXT_ITEM_PASSAGES is true. Rerun query to check for matches on text field.") + query_params.score_text_passage = true; + let es_query_on_text_passage = await build_es_query(query_params); + es_response = await request({ + url: `https://${req._info.es.address}/${req._info.es.index}/_search?search_type=dfs_query_then_fetch`, + method: "GET", + body: es_query_on_text_passage + }); + // check threshold - always '1' if not using embeddings + let threshold = (_.get(query_params, 'settings.EMBEDDINGS_ENABLE')) ? _.get(query_params,'settings.EMBEDDINGS_TEXT_PASSAGE_SCORE_THRESHOLD',0) : 1 + qnabot.log(`Score threshold for answer matches is: ${threshold}.`) + es_response = score_threshold_check(es_response, threshold) + gothits = _.get(es_response, 'hits.hits.length'); + matched_field = (gothits) ? "answer" : ""; + } + // apply topic tiebreaker to any equally ranked hits, trim to desired size, and set answersource to display in debug mode. if (gothits) { const newhits = hits_topic_tiebreaker(query_params.topic, es_response.hits.hits); diff --git a/lambda/es-proxy-layer/lib/esbodybuilder.js b/lambda/es-proxy-layer/lib/esbodybuilder.js index 414d01c11..3ecf77447 100644 --- a/lambda/es-proxy-layer/lib/esbodybuilder.js +++ b/lambda/es-proxy-layer/lib/esbodybuilder.js @@ -36,6 +36,13 @@ function build_query(params) { zero_terms_query: 'all', } }; + const filter_query_passage = { + 'passage': { + query: keywords, + minimum_should_match: _.get(params, 'minimum_should_match', '2<75%'), + zero_terms_query: 'all', + } + }; const match_query = { 'quniqueterms': { query: params.question, @@ -45,6 +52,7 @@ function build_query(params) { if (_.get(params, 'fuzziness')) { filter_query_unique_terms.quniqueterms.fuzziness = "AUTO"; filter_query_a.a.fuzziness = "AUTO"; + filter_query_passage.passage.fuzziness = 'AUTO'; match_query.quniqueterms.fuzziness = "AUTO"; } let query = bodybuilder(); @@ -56,6 +64,8 @@ function build_query(params) { if (keywords.length > 0) { if (_.get(params, 'score_answer')) { query = query.filter('match', filter_query_a); + } else if (_.get(params, 'score_text_passage')) { + query = query.filter('match', filter_query_passage); } else { query = query.filter('match', filter_query_unique_terms); } @@ -94,40 +104,50 @@ function build_query(params) { ).filterMinimumShouldMatch(1); if (_.get(params, 'settings.EMBEDDINGS_ENABLE')) { - const q_weight = _.get(params, 'settings.EMBEDDINGS_WEIGHT_QUESTION_FIELD', 1.0) - const a_weight = _.get(params, 'settings.EMBEDDINGS_WEIGHT_ANSWER_FIELD', 0.5) // do KNN embedding match for semantic similarity - if ( ! _.get(params, 'score_answer')) { - // match on q_vector (score_answer is false) - query = query.orQuery( - "nested", { - score_mode: 'max', - path: 'questions', - query: { - knn: { - "questions.q_vector": { - k: _.get(params, 'settings.EMBEDDINGS_KNN_K', 10), - vector: await get_embeddings("q", params.question, params.settings) - } - } - } - } - ); - } else { + if (params.score_answer) { // match on a_vector (score_answer is true) - query = query.orQuery( - "knn", { + query = query.orQuery('knn', { a_vector: { - k: _.get(params, 'settings.EMBEDDINGS_KNN_K', 10), - vector: await get_embeddings("q", params.question, params.settings), + k: _.get(params, 'settings.EMBEDDINGS_KNN_K', 10), + vector: await get_embeddings('q', params.question, params.settings) + } + }); + } else if (params.score_text_passage) { + // match on passage_vector (score_text_passage is true) + query = query.orQuery('knn', { + passage_vector: { + k: _.get(params, 'settings.EMBEDDINGS_KNN_K', 10), + vector: await get_embeddings('q', params.question, params.settings) } + }); + } else { + // match on q_vector (default) + query = query.orQuery('nested', { + score_mode: 'max', + path: 'questions', + query: { + knn: { + 'questions.q_vector': { + k: _.get(params, 'settings.EMBEDDINGS_KNN_K', 10), + vector: await get_embeddings('q', params.question, params.settings) + } + } } - ); + }); } } else { // No embeddings. Do terms and phrase matches instead, and add topic filters - if ( ! _.get(params, 'score_answer')) { - // match on questions (score_answer is false) + if (params.score_answer) { + // match on answers (score_answer is true) + query = query.orQuery('match', 'a', params.question); + query = query.orQuery('match_phrase', 'a', params.question); + } else if (params.score_text_passage) { + // match on text (score_text_passage is true) + query = query.orQuery('match', 'passage', params.question); + query = query.orQuery('match_phrase', 'passage', params.question); + } else { + // match on questions (default) query = query.orQuery( 'match', match_query ); @@ -139,10 +159,6 @@ function build_query(params) { }, q => q.query('match_phrase', 'questions.q', params.question) ); - } else { - // match on answers (score_answer is true) - query = query.orQuery('match', 'a', params.question); - query = query.orQuery('match_phrase', 'a', params.question); } let topic = _.get(params, 'topic'); if (topic) { @@ -175,7 +191,7 @@ function build_query(params) { } } query = query - .rawOption("_source",{"exclude": ["questions.q_vector", "a_vector"]}) + .rawOption("_source",{"exclude": ["questions.q_vector", "a_vector", "passage_vector"]}) .from(_.get(params, 'from', 0)) .size(_.get(params, 'size', 1)) .build(); diff --git a/lambda/es-proxy-layer/lib/handler.js b/lambda/es-proxy-layer/lib/handler.js index 5fcc51e49..28a74df7d 100644 --- a/lambda/es-proxy-layer/lib/handler.js +++ b/lambda/es-proxy-layer/lib/handler.js @@ -37,6 +37,11 @@ async function build_additem_embeddings(event, settings) { if (answer) { event.body.a_vector = await get_embeddings("a", answer, settings); } + // text item passage embeddings + const passage = _.get(event,"body.passage"); + if (passage) { + event.body.passage_vector = await get_embeddings("a", passage, settings); + } return event.body; } @@ -50,18 +55,19 @@ async function get_es_query(event, settings) { } let query_params = { question: question, - topic: _.get(event,'topic',''), - from: _.get(event,'from',0), + topic: _.get(event, 'topic', ''), + from: _.get(event, 'from', 0), size: size, - minimum_should_match: _.get(settings,'ES_MINIMUM_SHOULD_MATCH'), + minimum_should_match: _.get(settings, 'ES_MINIMUM_SHOULD_MATCH'), phrase_boost: _.get(settings, 'ES_PHRASE_BOOST'), - use_keyword_filters: _.get(settings,'ES_USE_KEYWORD_FILTERS'), - keyword_syntax_types: _.get(settings,'ES_KEYWORD_SYNTAX_TYPES'), - syntax_confidence_limit: _.get(settings,'ES_SYNTAX_CONFIDENCE_LIMIT'), + use_keyword_filters: _.get(settings, 'ES_USE_KEYWORD_FILTERS'), + keyword_syntax_types: _.get(settings, 'ES_KEYWORD_SYNTAX_TYPES'), + syntax_confidence_limit: _.get(settings, 'ES_SYNTAX_CONFIDENCE_LIMIT'), fuzziness: _.get(settings, 'ES_USE_FUZZY_MATCH'), - es_expand_contractions: _.get(settings,"ES_EXPAND_CONTRACTIONS"), - qnaClientFilter: _.get(event,'client_filter',''), - score_answer: (_.get(event,'score_answer','false') === "true") ? true : false, + es_expand_contractions: _.get(settings, 'ES_EXPAND_CONTRACTIONS'), + qnaClientFilter: _.get(event, 'client_filter', ''), + score_answer: _.get(event, 'score_answer', 'false') === 'true' ? true : false, + score_text_passage: _.get(event, 'score_text_passage', 'false') === 'true' ? true : false, settings: settings }; return build_es_query(query_params); @@ -133,7 +139,8 @@ module.exports= async (event, context, callback) => { kendraIndex: kendra_index, question: question, qnaClientFilter: _.get(event,'client_filter',''), - score_answer: (_.get(event,'score_answer','false') === "true") ? true : false + score_answer: (_.get(event,'score_answer','false') === "true") ? true : false, + score_text_passage: _.get(event, 'score_text_passage', 'false') === 'true' ? true : false, } let response let okKendraQuery = !(await open_es.isESonly(req,params)) diff --git a/lambda/es-proxy-layer/lib/kendra.js b/lambda/es-proxy-layer/lib/kendra.js index 5c1e99b25..c2aec6341 100644 --- a/lambda/es-proxy-layer/lib/kendra.js +++ b/lambda/es-proxy-layer/lib/kendra.js @@ -18,6 +18,18 @@ const { filter } = require('bluebird'); let kendraIndexes = undefined; const qnabot = require("qnabot/logging") +function allow_kendra_result(kendra_result, minimum_score, response_types){ + if (!type_filter(response_types,kendra_result)) { + qnabot.log(`Result removed: Type [${kendra_result.Type}] not in allowed types [${response_types}] - Passage: ${_.get(kendra_result,"DocumentExcerpt.Text")}`); + return false; + } + if (!confidence_filter(minimum_score,kendra_result)) { + qnabot.log(`Result removed: ScoreConfidence [${_.get(kendra_result,"ScoreAttributes.ScoreConfidence")}] below threshold [${minimum_score}] - Passage: ${_.get(kendra_result,"DocumentExcerpt.Text")}`); + return false; + } + qnabot.log(`Result allowed: Type [${kendra_result.Type}], ScoreConfidence [${_.get(kendra_result,"ScoreAttributes.ScoreConfidence")}] - Passage: ${_.get(kendra_result,"DocumentExcerpt.Text")}`); + return true; +} function confidence_filter(minimum_score,kendra_result){ var confidences = ["LOW","MEDIUM","HIGH","VERY_HIGH"] @@ -27,12 +39,11 @@ function confidence_filter(minimum_score,kendra_result){ return true; } confidences = confidences.slice(index) - qnabot.log("Testing confidences: Allowed - " + JSON.stringify(confidences) + " Actual - " + _.get(kendra_result,"ScoreAttributes.ScoreConfidence") ) const found = confidences.find(element => element == _.get(kendra_result,"ScoreAttributes.ScoreConfidence")) != undefined return found } -function response_filter(response_types,kendra_result){ +function type_filter(response_types,kendra_result){ return response_types.includes(kendra_result.Type) } function create_hit(answermessage,markdown,ssml,hit_count,debug_results,kendra){ @@ -42,7 +53,7 @@ function create_hit(answermessage,markdown,ssml,hit_count,debug_results,kendra){ "markdown": markdown, "ssml":ssml }, - "type": "qna", + "type": "text", "questions": [ ], "answersource": "KENDRA FALLBACK", @@ -118,7 +129,7 @@ function kendraRequester(kendraClient,params,resArray) { } else { data.originalKendraIndexId = indexId; - qnabot.log("Data from Kendra request:" + JSON.stringify(data, null, 2)); + qnabot.log("Kendra response:" + JSON.stringify(data, null, 2)); resArray.push(data); resolve(data); } @@ -186,8 +197,7 @@ function signS3URL(url, expireSecs) { key = url.split('/').slice(3).join('/'); } if (bucket && key) { - qnabot.log("Attempt to convert S3 url to a signed URL: ",url); - qnabot.log("Bucket: ", bucket, " Key: ", key) ; + qnabot.debug("Convert S3 url to a signed URL: ",url, "Bucket: ", bucket, " Key: ", key); try { const s3 = new AWS.S3() ; const signedurl = s3.getSignedUrl('getObject', { @@ -201,7 +211,7 @@ function signS3URL(url, expireSecs) { qnabot.log("Error signing S3 URL (returning original URL): ", err) ; } } else { - qnabot.log("URL is not an S3 url - return unchanged: ",url); + qnabot.debug("URL is not an S3 url - return unchanged: ",url); } return url; } @@ -246,7 +256,7 @@ function isSyncedFromQnABot(kendra_result){ return false; } - let hit = JSON.parse(element.DocumentURI); + let hit = JSON.parse(kendra_result.DocumentURI); if (_.get(hit,"_source_qid")) { qnabot.warn("The Kendra result was synced from QnABot. Skipping...") return true @@ -314,10 +324,19 @@ async function routeKendraRequest(event, context) { let origQuestion = event.req["_event"]["origQuestion"]; let question = event.req["question"]; let userDetectedLocale = _.get(event.req, 'session.qnabotcontext.userLocale'); + let standalone_query = _.get(event.req, 'llm_generated_query.concatenated'); let useOriginalLanguageQuery = kendraIndexedLanguages.includes(userDetectedLocale, 0) && origQuestion && question && origQuestion!=question; + if (standalone_query) { + useOriginalLanguageQuery = false; + qnabot.log("Using LLM generated standalone query: " + standalone_query); + } qnabot.log("useOriginalLanguageQuery: " + useOriginalLanguageQuery); + // when not using LLM QA, if Kendra results contain topAnswer we return that, and ignore all else.. + // BUT this is not helpful when using the LLM to generate an answer.. in this case we should not apply + // any special handling for 'top answer' + const returnTopAnswer = (_.get(event.req._settings, "LLM_QA_ENABLE")) ? false : true; // This function can handle configuration with an array of kendraIndexes. // Iterate through this area and perform queries against Kendra. @@ -361,7 +380,7 @@ async function routeKendraRequest(event, context) { let topAnswerMessage = event.req["_settings"]["ALT_SEARCH_KENDRA_TOP_ANSWER_MESSAGE"] + "\n\n"; //"Amazon Kendra suggested answer. \n\n "; let topAnswerMessageMd = event.req["_settings"]["ALT_SEARCH_KENDRA_TOP_ANSWER_MESSAGE"] == "" ? "" : `*${event.req["_settings"]["ALT_SEARCH_KENDRA_TOP_ANSWER_MESSAGE"]}* \n `; let answerMessage = event.req["_settings"]["ALT_SEARCH_KENDRA_ANSWER_MESSAGE"]; - let answerMessageMd = event.req["_settings"]["ALT_SEARCH_KENDRA_ANSWER_MESSAGE"] == "" ? "" : `*${answerMessage}* \n `; + let answerMessageMd = event.req["_settings"]["ALT_SEARCH_KENDRA_ANSWER_MESSAGE"] == "" ? "" : `**${answerMessage}** \n `; let faqanswerMessage = event.req["_settings"]["ALT_SEARCH_KENDRA_FAQ_MESSAGE"] + "\n\n"; //'Answer from Amazon Kendra FAQ.' let faqanswerMessageMd = event.req["_settings"]["ALT_SEARCH_KENDRA_FAQ_MESSAGE"] == "" ? "" : `*${event.req["_settings"]["ALT_SEARCH_KENDRA_FAQ_MESSAGE"]}* \n` let minimum_score = event.req["_settings"]["ALT_SEARCH_KENDRA_FALLBACK_CONFIDENCE_SCORE"]; @@ -388,13 +407,10 @@ async function routeKendraRequest(event, context) { if (res && res.ResultItems.length > 0) { res.ResultItems.forEach(function (element, i) { - if(!confidence_filter(minimum_score,element)){ - return; - } - if(!response_filter(searchTypes,element)){ + if(!allow_kendra_result(element, minimum_score, searchTypes)){ return; } - if(seenTop){ + if(returnTopAnswer && seenTop){ return; } /* Note - only the first answer will be provided back to the requester */ @@ -412,7 +428,7 @@ async function routeKendraRequest(event, context) { elem = sorted_highlights[j]; let offset = 4*j; - if (elem.TopAnswer == true) { // if top answer is found, then answer is abbreviated to this phrase + if (returnTopAnswer && elem.TopAnswer == true) { // if top answer is found, then answer is abbreviated to this phrase seenTop = true; answerMessageMd = topAnswerMessageMd; answerTextMd = addMarkdownHighlights(answerTextMd, elem.BeginOffset+offset, elem.EndOffset+offset, true) ; @@ -592,7 +608,7 @@ async function routeKendraRequest(event, context) { if (hit) { hit.autotranslate = useOriginalLanguageQuery ? false : true; } - qnabot.log("Returning event: ", JSON.stringify(hit, null, 2)); + qnabot.debug("Kendra Fallback result: ", JSON.stringify(hit, null, 2)); return hit; } diff --git a/lambda/es-proxy-layer/lib/kendraQuery.js b/lambda/es-proxy-layer/lib/kendraQuery.js index 0f88838ea..15c1136e6 100644 --- a/lambda/es-proxy-layer/lib/kendraQuery.js +++ b/lambda/es-proxy-layer/lib/kendraQuery.js @@ -12,18 +12,25 @@ const qnabot = require("qnabot/logging") const open_es = require("./es_query") +function allow_kendra_result(kendra_result, minimum_score){ + if (!confidence_filter(minimum_score,kendra_result)) { + qnabot.log(`Result removed: ScoreConfidence [${_.get(kendra_result,"ScoreAttributes.ScoreConfidence")}] below threshold [${minimum_score}] - Passage: ${_.get(kendra_result,"DocumentExcerpt.Text")}`); + return false; + } + qnabot.log(`Result allowed: Type [${kendra_result.Type}], ScoreConfidence [${_.get(kendra_result,"ScoreAttributes.ScoreConfidence")}] - Passage: ${_.get(kendra_result,"DocumentExcerpt.Text")}`); + return true; +} + function confidence_filter(minimum_score,kendra_result){ var confidences = ["LOW","MEDIUM","HIGH","VERY_HIGH"] var index = confidences.findIndex( i => i == minimum_score.toUpperCase()) if(index == undefined){ - qnabot.log("Warning: ALT_SEARCH_KENDRA_CONFIDENCE_SCORE should be one of 'VERY_HIGH'|'HIGH'|'MEDIUM'|'LOW'") + qnabot.log("Warning: ALT_SEARCH_KENDRA_FALLBACK_CONFIDENCE_SCORE should be one of 'VERY_HIGH'|'HIGH'|'MEDIUM'|'LOW'") return true; } confidences = confidences.slice(index) - qnabot.log("Testing confidences: Allowed - " + JSON.stringify(confidences) + " Actual - " + _.get(kendra_result,"ScoreAttributes.ScoreConfidence") ) const found = confidences.find(element => element == _.get(kendra_result,"ScoreAttributes.ScoreConfidence")) != undefined return found - } @@ -45,7 +52,7 @@ function kendraRequester(kendraClient,params,resArray) { } else { data.originalKendraIndexId = indexId; - qnabot.log("Data from Kendra request:" + JSON.stringify(data, null, 2)); + qnabot.log("Kendra response:" + JSON.stringify(data, null, 2)); resArray.push(data); resolve(data); } @@ -126,7 +133,7 @@ async function routeKendraRequest(request_params) { for (i=0; i { - qnabot.log("kendra query request: " + JSON.stringify(request_params)); + qnabot.log("Kendra request params: " + JSON.stringify(request_params)); return routeKendraRequest(request_params); }; diff --git a/lambda/es-proxy-layer/lib/kendraRetrieve.js b/lambda/es-proxy-layer/lib/kendraRetrieve.js new file mode 100644 index 000000000..31cbb61df --- /dev/null +++ b/lambda/es-proxy-layer/lib/kendraRetrieve.js @@ -0,0 +1,149 @@ +var _ = require('lodash'); +const AWS = require('aws-sdk'); +const qnabot = require("qnabot/logging") + + +function signS3URL(url, expireSecs) { + var bucket, key; + if (url.search(/\/s3[.-](\w{2}-\w{4,9}-\d\.)?amazonaws\.com/) != -1) { + //bucket in path format + bucket = url.split('/')[3]; + key = url.split('/').slice(4).join('/'); + } + if (url.search(/\.s3[.-](\w{2}-\w{4,9}-\d\.)?amazonaws\.com/) != -1) { + //bucket in hostname format + let hostname = url.split("/")[2]; + bucket = hostname.split(".")[0]; + key = url.split('/').slice(3).join('/'); + } + if (bucket && key) { + qnabot.debug("Convert S3 url to a signed URL: ",url, "Bucket: ", bucket, " Key: ", key); + try { + const s3 = new AWS.S3() ; + const signedurl = s3.getSignedUrl('getObject', { + Bucket: bucket, + Key: key, + Expires: expireSecs + }) + qnabot.log("Signed URL: ", signedurl); + url = signedurl; + } catch (err) { + qnabot.log("Error signing S3 URL (returning original URL): ", err) ; + } + } else { + qnabot.debug("URL is not an S3 url - return unchanged: ",url); + } + return url; +} + +function createHit(docs, hitCount){ + if(hitCount <= 0){ + return null + } + + let hit = { + "a": docs, + "alt": { + "markdown": docs, + "ssml": "" + }, + "type": "text", + "questions": [], + "answersource": "KENDRA RETRIEVE API", + "hit_count": hitCount, + "debug": [] + } + qnabot.log("createHit: ", JSON.stringify(hit, null, 2)) + return hit +} + +function getIndexIDs(req){ + let parsedIndexes + let indexes = req["_settings"]["ALT_SEARCH_KENDRA_INDEXES"] ? req["_settings"]["ALT_SEARCH_KENDRA_INDEXES"] : process.env.KENDRA_INDEXES + if (indexes && indexes.length) { + try { + // parse JSON array of kendra indexes + parsedIndexes = JSON.parse(indexes); + } catch (err) { + // assume setting is a string containing single index + parsedIndexes = [ indexes ]; + } + return parsedIndexes + } + else{ + throw new Error('Undefined Kendra Indexes'); + } +} + +function getResult(resp, index, signS3Urls, expireSeconds){ + let r = resp["ResultItems"][index] + let doc_excerpt = r["Content"] + let doc_title = r["DocumentTitle"] + let doc_uri = r["DocumentURI"] + if (signS3Urls){ + doc_uri = signS3URL(doc_uri, expireSeconds) + } + let link = `[${doc_title}](${doc_uri})` + let result = `${doc_excerpt}\n\nSource Link: ${link}` + return result +} + + +function getQuery(req){ + let origQuestion = req["_event"]["origQuestion"]; + let question = req["question"]; + let userDetectedLocale = _.get(req, 'session.qnabotcontext.userLocale'); + let standaloneQuery = _.get(req, 'llm_generated_query.concatenated'); + + let kendraIndexedLanguages = _.get(req["_settings"], + "KENDRA_INDEXED_DOCUMENTS_LANGUAGES",["en"]); + qnabot.log("Retrieved Kendra multi-language settings: " + kendraIndexedLanguages); + + let useOriginalLanguageQuery = kendraIndexedLanguages.includes(userDetectedLocale, 0) + && origQuestion && question && origQuestion!=question; + if (standaloneQuery) { + useOriginalLanguageQuery = false; + qnabot.log("Using LLM generated standalone query: " + standaloneQuery); + } + qnabot.log("useOriginalLanguageQuery: " + useOriginalLanguageQuery); + return useOriginalLanguageQuery ? origQuestion : question +} + +async function kendraRetrieve(kendraClient, req){ + let kcount = _.get(req["_settings"],"ALT_SEARCH_KENDRA_MAX_DOCUMENT_COUNT",2) + let signS3Urls = _.get(req["_settings"],"ALT_SEARCH_KENDRA_S3_SIGNED_URLS",true) + let expireSeconds = _.get(req["_settings"],"ALT_SEARCH_KENDRA_S3_SIGNED_URL_EXPIRE_SECS",300) + + + let kindexIDs = getIndexIDs(req) + let kquery = getQuery(req) + let response = await kendraClient.retrieve({ + IndexId: kindexIDs[0], + QueryText: kquery.trim(), + PageSize: kcount + }).promise() + qnabot.log("Debug: Retrieve API response: ", JSON.stringify(response, null, 2)) + + let respLen = response["ResultItems"].length + qnabot.log("Debug: Retrieve response length: ", respLen) + + //process the results of the retrieve API + let rCount = respLen > kcount ? kcount : respLen + + let results = [] + for(let i = 0; i< rCount; i++){ + let result = getResult(response, i, signS3Urls, expireSeconds) + results.push(result) + } + docs = results.join("\n---\n") + hit = createHit(docs, rCount) + return hit +} + +exports.handler = async (event, context) => { + qnabot.debug("event: " + JSON.stringify(event, null, 2)); + const kendraClient = new AWS.Kendra({apiVersion: '2019-02-03', region: process.env.AWS_REGION || 'us-east-1'}) + hit = await kendraRetrieve(kendraClient, event) + + return hit; +}; \ No newline at end of file diff --git a/lambda/es-proxy-layer/lib/llm.js b/lambda/es-proxy-layer/lib/llm.js new file mode 100644 index 000000000..53e9c23eb --- /dev/null +++ b/lambda/es-proxy-layer/lib/llm.js @@ -0,0 +1,288 @@ +const _ = require('lodash'); +const aws = require('aws-sdk'); +const qnabot = require('qnabot/logging'); + +const ChatMessageHistory = require("langchain/memory").ChatMessageHistory; +const BufferMemory = require("langchain/memory").BufferMemory; +const PromptTemplate = require("langchain/prompts").PromptTemplate; + +// +// Private functions +// + +const default_params_stg = `{"temperature":0}`; + +// make QA prompt from template +async function make_qa_prompt(req, promptTemplateStr, context, input, query) { + const chatMessageHistory = await chatMemoryParse(_.get(req._userInfo, "chatMessageHistory","[]"), req._settings.LLM_CHAT_HISTORY_MAX_MESSAGES); + const memory = new BufferMemory({ chatHistory: chatMessageHistory }); + const history = (await memory.loadMemoryVariables()).history; + const promptTemplate = new PromptTemplate({ + template: promptTemplateStr, + inputVariables: ["history", "context", "input", "query"], + }); + const prompt = await promptTemplate.format({ + history: history, + context: context, + input: input, + query: query, + }); + return [memory, history, promptTemplate, prompt]; +} +// make generate query prompt from template +async function make_qenerate_query_prompt(req, promptTemplateStr) { + const chatMessageHistory = await chatMemoryParse(_.get(req._userInfo, "chatMessageHistory","[]"), req._settings.LLM_CHAT_HISTORY_MAX_MESSAGES); + const memory = new BufferMemory({ chatHistory: chatMessageHistory }); + const history = (await memory.loadMemoryVariables()).history; + const promptTemplate = new PromptTemplate({ + template: promptTemplateStr, + inputVariables: ["history", "input"], + }); + const prompt = await promptTemplate.format({ + history: history, + input: req.question, + }); + return [memory, history, promptTemplate, prompt]; +} + +// Invoke LLM via SageMaker endpoint running HF_MODEL tiiuae/falcon-40b-instruct +async function invoke_sagemaker(prompt, model_params) { + const sm = new aws.SageMakerRuntime({region: process.env.AWS_REGION || 'us-east-1'}); + const body = JSON.stringify({ + 'inputs': prompt, + 'parameters': model_params + }); + let response; + qnabot.log(`Invoking SageMaker endpoint: ${process.env.LLM_SAGEMAKERENDPOINT}`); + try { + let smres = await sm.invokeEndpoint({ + EndpointName: process.env.LLM_SAGEMAKERENDPOINT, + ContentType: 'application/json', + Body: body, + }).promise(); + const sm_body = JSON.parse(Buffer.from(smres.Body, 'utf-8').toString()); + qnabot.log('SM response body:', sm_body); + response = sm_body[0].generated_text; + } catch (e) { + qnabot.warn("EXCEPTION:", e.stack); + throw new Error('Sagemaker exception: ' + e.message.substring(0, 500) + '...'); + } + return response; +} +async function generate_query_sagemaker(req, promptTemplateStr) { + const model_params = JSON.parse(req._settings.LLM_GENERATE_QUERY_MODEL_PARAMS || default_params_stg); + const [memory, history, promptTemplate, prompt] = await make_qenerate_query_prompt(req, promptTemplateStr); + qnabot.log(`Prompt: \nGENERATE QUERY PROMPT==>\n${prompt}\n<==PROMPT`); + return invoke_sagemaker(prompt, model_params); +} +async function get_qa_sagemaker(req, promptTemplateStr, context) { + const model_params = JSON.parse(req._settings.LLM_QA_MODEL_PARAMS || default_params_stg); + const input = get_question(req); + const query = get_query(req); + const [memory, history, promptTemplate, prompt] = await make_qa_prompt(req, promptTemplateStr, context, input, query); + qnabot.log(`QUESTION ANSWERING PROMPT: \nPROMPT==>\n${prompt}\n<==PROMPT`); + return invoke_sagemaker(prompt, model_params); +} + + +// Invoke LLM via custom Lambda abstraction +async function invoke_lambda(prompt, model_params, settings) { + const lambda= new aws.Lambda({region: process.env.AWS_REGION || "us-east-1"}); + const body = JSON.stringify({ + 'prompt': prompt, + 'parameters': model_params, + 'settings': settings + }); + + + qnabot.log(`Invoking Lambda: ${process.env.LLM_LAMBDA_ARN}`); + try { + let lambdares =await lambda.invoke({ + FunctionName:process.env.LLM_LAMBDA_ARN, + InvocationType:'RequestResponse', + Payload: body, + }).promise(); + let payload=JSON.parse(lambdares.Payload); + qnabot.log('Lambda response payload:', payload); + + if (payload.generated_text) { + return payload.generated_text; + } + + qnabot.warn("ERROR: Lambda response error. Returned payload missing 'generated_text' property:", payload); + if (payload.errorMessage) { + throw new Error(payload.errorMessage); + } + throw new Error("LLM inference failed."); + } catch (e) { + qnabot.warn("EXCEPTION:", e.stack); + throw new Error('Lambda exception: ' + e.message.substring(0, 500) + '...'); + } +} +async function generate_query_lambda(req, promptTemplateStr) { + const model_params = JSON.parse(req._settings.LLM_GENERATE_QUERY_MODEL_PARAMS || default_params_stg); + const settings = req._settings; + const [memory, history, promptTemplate, prompt] = await make_qenerate_query_prompt(req, promptTemplateStr); + qnabot.log(`Prompt: \nGENERATE QUERY PROMPT==>\n${prompt}\n<==PROMPT`); + return invoke_lambda(prompt, model_params, settings); +} +async function get_qa_lambda(req, promptTemplateStr, context) { + const model_params = JSON.parse(req._settings.LLM_QA_MODEL_PARAMS || default_params_stg); + const settings = req._settings; + // parse and serialise chat history to manage max messages + const input = get_question(req); + const query = get_query(req); + const [memory, history, promptTemplate, prompt] = await make_qa_prompt(req, promptTemplateStr, context, input, query); + qnabot.log(`QUESTION ANSWERING PROMPT: \nPROMPT==>\n${prompt}\n<==PROMPT`); + return invoke_lambda(prompt, model_params, settings); +} + +function clean_standalone_query(query) { + let clean_query = query; + // remove preamble, if any + clean_query = clean_query.replace(/^Here .*? the standalone question.*$/img, ''); + // remove newlines + clean_query = clean_query.replace(/\n/g, ' '); + // No more than 1000 characters - for Kendra query compatability - https://docs.aws.amazon.com/kendra/latest/dg/API_Query.html + clean_query = clean_query.slice(0,1000); + // limit output to one question.. truncate any runaway answers that shouldn't be included in the query. + const q_pos = clean_query.indexOf('?'); + if (q_pos > -1) { + clean_query = clean_query.slice(0,q_pos + 1); + } + // trim leading or trailing whitespace + clean_query = clean_query.trim(); + return clean_query; +} + +// +// Exported functions +// + +// clean unwanted text artifacts from the provided context.. +const clean_context = function clean_context(context, req) { + let clean_context = context; + // remove URLS from Kendra passages + clean_context = clean_context.replace(/^\s*Source Link:.*$/mg, ''); + // remove Kendra prefix messages + if (req._settings.ALT_SEARCH_KENDRA_ANSWER_MESSAGE) { + clean_context = clean_context.replace(new RegExp(req._settings.ALT_SEARCH_KENDRA_ANSWER_MESSAGE, 'g'), ''); + } + if (req._settings.ALT_SEARCH_KENDRA_FAQ_MESSAGE) { + clean_context = clean_context.replace(new RegExp(req._settings.ALT_SEARCH_KENDRA_FAQ_MESSAGE, 'g'), ''); + } + if (req._settings.ALT_SEARCH_KENDRA_TOP_ANSWER_MESSAGE) { + clean_context = clean_context.replace(new RegExp(req._settings.ALT_SEARCH_KENDRA_TOP_ANSWER_MESSAGE, 'g'), ''); + } + return clean_context; +} + +// LangChain chatMessageHistory serialize (to JSON) and parse (from JSON) +// Chat history persistance is maintained via userInfo, managed from query.js, and stored in DynamoDB with other userInfo. +async function chatMemorySerialise(chatMessageHistory, max=50, human_prefix = "Human", ai_prefix = "AI") { + const messages = await chatMessageHistory.getMessages(); + const obj_messages = []; + for (const m of messages) { + let role; + if (m._getType() === "human") { + role = human_prefix; + } + else if (m._getType() === "ai") { + role = ai_prefix; + } + else { + throw new Error(`Got unsupported message type: ${m}`); + } + obj_messages.push({[role]: m.text}); + } + return JSON.stringify(obj_messages.slice(-max)); + } +async function chatMemoryParse(json_messages, max=50) { + const chatMessageHistory = new ChatMessageHistory(); + const obj_messages = JSON.parse(json_messages).slice(-max); + qnabot.log(`Chat Message History (capped at ${max}): `, json_messages); + for (const m of obj_messages) { + if (m.Human) { + chatMessageHistory.addUserMessage(m.Human); + } + else if (m.AI) { + chatMessageHistory.addAIChatMessage(m.AI); + } + else { + throw new Error(`Got unsupported message type: ${m}`); + } + } + return chatMessageHistory; + } + + // return the question to use in the QA prompt +function get_question(req) { + const question = _.get(req,"llm_generated_query.orig", req.question); + return question; +} +function get_query(req) { + const query = _.get(req,"llm_generated_query.result", req.question); + return query; +} + +// generate_query: re-write utterance using chat history if needed, to make it standalone from prior conversation context. +const generate_query = async function generate_query(req) { + qnabot.log(`Use LLM (${req._settings.LLM_API}) to convert a follow up question to a standalone search query containing required context from chat history`); + const origQuestion = req.question; + // TODO - Can this also tell me if a query is needed, or if the LLM/chatHistory already has the answer + let promptTemplateStr = req._settings.LLM_GENERATE_QUERY_PROMPT_TEMPLATE || `

Human: Given the following conversation and a follow up input, if the follow up input is a question please rephrase that question to be a standalone question, otherwise return the input unchanged.

Chat History:
Follow Up Input: {input}

Assistant:`; + promptTemplateStr = promptTemplateStr.replace(/
/mg, "\n"); + let newQuery; + const start = Date.now(); + if (req._settings.LLM_API == "SAGEMAKER") { + // TODO refactor when langchainJS supports Sagemaker + newQuery = await generate_query_sagemaker(req, promptTemplateStr); + } else if (req._settings.LLM_API == "LAMBDA") { + newQuery = await generate_query_lambda(req, promptTemplateStr); + } else { + throw new Error(`Error: Unsupported LLM_API type: ${req._settings.LLM_API}`); + } + const end = Date.now(); + const timing = `${end - start} ms`; + qnabot.debug(`LLM response before running clean_standalone_query(): ${newQuery}`); + newQuery = clean_standalone_query(newQuery); + const concatQuery = `${origQuestion} / ${newQuery}`; + qnabot.log(`Original question: ${origQuestion} => New question: ${newQuery}. Use concatenation for retrieval query: ${concatQuery}`); + req.question = concatQuery; + req.llm_generated_query = { + orig: origQuestion, + result: newQuery, + concatenated: concatQuery, + timing: timing + }; + return req; +} + +const get_qa = async function get_qa(req, context) { + qnabot.log(`LLM (${req._settings.LLM_API}) Retrieval Augmented Generation (RAG) to answer user's question from search result context.`); + let promptTemplateStr = req._settings.LLM_QA_PROMPT_TEMPLATE || `

Human: You are an AI chatbot. Carefully read the following context and conversation history and then provide a short answer to question at the end. If the answer cannot be determined from the history or the context, reply saying "Sorry, I don't know".

Context: {context}

History:
{history}

Human: {input}

Assistant:`; + promptTemplateStr = promptTemplateStr.replace(/
/mg, "\n"); + context = clean_context(context, req); + let answer; + if (req._settings.LLM_API == "SAGEMAKER") { + // TODO refactor when langchainJS supports Sagemaker + answer = await get_qa_sagemaker(req, promptTemplateStr, context); + } else if (req._settings.LLM_API == "LAMBDA") { + answer = await get_qa_lambda(req, promptTemplateStr, context); + } else { + throw new Error(`Error: Unsupported LLM_API type: ${req._settings.LLM_API}`); + } + qnabot.log(`Question: ${req.question}`); + qnabot.log(`Context: ${context}`); + qnabot.log(`Answer: ${answer}`); + return answer; +} + +module.exports = { + clean_context:clean_context, + chatMemorySerialise:chatMemorySerialise, + chatMemoryParse:chatMemoryParse, + get_question:get_question, + generate_query:generate_query, + get_qa:get_qa +} \ No newline at end of file diff --git a/lambda/es-proxy-layer/lib/query.js b/lambda/es-proxy-layer/lib/query.js index e07ddb836..2b9fb1a9b 100755 --- a/lambda/es-proxy-layer/lib/query.js +++ b/lambda/es-proxy-layer/lib/query.js @@ -5,10 +5,14 @@ var handlebars = require('./handlebars'); var translate = require('./translate'); var kendra = require('./kendraQuery'); var kendra_fallback = require('./kendra'); -const qnabot = require('qnabot/logging') -const qna_settings = require('qnabot/settings') -const open_es = require('./es_query') -const {VM} = require('vm2'); +const kendra_retrieve = require('./kendraRetrieve'); +const qnabot = require('qnabot/logging'); +const qna_settings = require('qnabot/settings'); +const open_es = require('./es_query'); +const llm = require('./llm'); +const staticEval = require('static-eval'); +const esprimaParse = require('esprima').parse; + // use DEFAULT_SETTINGS_PARAM as random encryption key unique to this QnABot installation var key = _.get(process.env, 'DEFAULT_SETTINGS_PARAM', 'fdsjhf98fd98fjh9 du98fjfd 8ud8fjdf'); @@ -54,12 +58,11 @@ async function run_query_kendra(req, query_params) { } } if (alt_kendra_idxs.includes(request_params.kendra_faq_index)) { - qnabot.log('optimizing for KendraFallback'); + qnabot.debug('optimizing for KendraFallback'); request_params['same_index'] = true ; } var kendra_response = await kendra.handler(request_params); - qnabot.log(`Response from run_query_kendra => ${JSON.stringify(kendra_response)}` ) if (_.get(kendra_response, 'hits.hits[0]._source')) { _.set(kendra_response, 'hits.hits[0]._source.answersource', 'Kendra FAQ'); } @@ -105,7 +108,7 @@ function merge_next(hit1, hit2) { if (hit1 === undefined) { return hit2; } - qnabot.log('Merge chained items'); + qnabot.debug('Merge chained items'); // merge plaintext answer if (hit1 && hit1.a) { hit2.a = hit1.a + hit2.a; @@ -116,7 +119,7 @@ function merge_next(hit1, hit2) { if (md1 && md2) { _.set(hit2, 'alt.markdown', md1 + '\n' + md2); } else { - qnabot.log('Markdown field missing from one or both items; skip markdown merge'); + qnabot.debug('Markdown field missing from one or both items; skip markdown merge'); } // merge SSML, if present in both items var ssml1 = _.get(hit1, 'alt.ssml'); @@ -128,7 +131,7 @@ function merge_next(hit1, hit2) { // concatenate, and re-wrap with tags _.set(hit2, 'alt.ssml', '' + ssml1 + ' ' + ssml2 + ''); } else { - qnabot.log('SSML field missing from one or both items; skip SSML merge'); + qnabot.debug('SSML field missing from one or both items; skip SSML merge'); } // build arrays of Lambda Hooks and arguments var lambdahooks = _.get(hit1, 'lambdahooks',[]); @@ -148,78 +151,100 @@ function merge_next(hit1, hit2) { _.set(hit2, 'lambdahooks', lambdahooks); // all other fields inherited from item 2 - qnabot.log('Chained items merged:', hit2); + qnabot.debug('Items merged:', hit2); return hit2; } -async function prepend_cfaq_answer(query, hit, cfaq_prefix, cfaq_endpoint, cfaq_domain, cfaq_index, cfaq_n_ctx) { - const sm = new aws.SageMakerRuntime({region:'us-east-1'}); - const history = {history: {L: {}}}; - const data = { - query: query.trim(), - dial_hist: history, - domain: cfaq_domain, - index_id: cfaq_index, - n_ctx: cfaq_n_ctx, - }; - const body = JSON.stringify(data); - let cfaq_answer; - console.log("Invoking CFAQ SM Endpoint"); - try { - let smres = await sm.invokeEndpoint({ - EndpointName:cfaq_endpoint, - ContentType:'text/csv', - Body:body, - }).promise(); - const sm_body = JSON.parse(Buffer.from(smres.Body, 'utf-8').toString()); - qnabot.log("CFAQ response body:", sm_body); - cfaq_answer = sm_body.text.trim(); - } catch (e) { - console.log(e) - cfaq_answer = "CFAQ exception: " + e.message.substring(0, 250) + "..."; - } - qnabot.log("CFAQ answer:", cfaq_answer); - +function prepend_llm_qa_answer(prefix, qa_answer, hit) { // prepend sm answer to plaintext and markdown - hit.a = `${cfaq_prefix}\n\n${cfaq_answer}\n\n${hit.a}`; - hit.alt.markdown = `*${cfaq_prefix}*\n\n**${cfaq_answer}**\n\n${hit.alt.markdown}`; + hit.a = [qa_answer, hit.a].join("\n\n"); + hit.alt.markdown = [qa_answer, hit.alt.markdown].join("\n\n"); // replace ssml with just the short answer for concise voice responses - hit.alt.ssml = cfaq_answer; - qnabot.log("modified hit:", JSON.stringify(hit)); + hit.alt.ssml = qa_answer; + prefix = prefix.trim(); + if(prefix){ + hit.a = [prefix, hit.a].join("\n\n"); + hit.alt.markdown = [`**${prefix}**`, hit.alt.markdown].join("\n\n"); + } + qnabot.log("modified hit:", JSON.stringify(hit)); return hit; } -async function post_process_with_sagemaker_endpoint(question, hit, sagemaker_qa_prefix, sm_endpoint, sm_confidence_threshold) { - const sm = new aws.SageMakerRuntime({region:'us-east-1'}); - const data = { - inputs: { - question: question, - context: hit.a, +function get_sourceLinks_from_passages(inputText) { + const sourceLinkPattern = /^\s*Source Link:(.*)$/gm; + let matches, sourceLinks = []; + + while ((matches = sourceLinkPattern.exec(inputText)) !== null) { + sourceLinks.push(matches[1].trim().replace(/^"|"$/g, '')); + } + + const uniqueLinks = [...new Set(sourceLinks)]; + return uniqueLinks.length > 0 ? `Sources: ${uniqueLinks.join(', ')}` : ""; +} + +async function run_llm_qa(req, hit) { + + if ( ! req._settings.LLM_QA_ENABLE ) { + // nothing to do + return hit; + } + + // LLM_QA_ENABLE is TRUE + const debug = req._settings.ENABLE_DEBUG_RESPONSES; + const context = hit.a; + if (req._settings.LLM_QA_SHOW_CONTEXT_TEXT == false) { + // remove context text.. hit will contain only the QA Summary output + hit.a = ""; + hit.alt.markdown = ""; + hit.alt.ssml = ""; + } else { + // Context provided only in markdown channel (excluded from chat memory) + hit.a = ""; + const ctx = llm.clean_context(hit.alt.markdown, req); + hit.alt.markdown = `
+ Context +

${ctx}

+
+
+ `; + qnabot.debug(`Markdown: ${hit.alt.markdown}`); + hit.alt.ssml = ""; + } + + if (hit.refMarkdown && req._settings.LLM_QA_SHOW_SOURCE_LINKS) { + hit.alt.markdown = `${hit.alt.markdown}\n${hit.refMarkdown}`; + } + + const start = Date.now(); + let answer + try{ + answer = await llm.get_qa(req, context); + } + catch(e){ + qnabot.warn(`[ERROR] Fatal LLM Exception, please check logs for details: ${e.message}`); + qnabot.warn("[INFO] Setting hits to undefined to trigger no_hits workflow"); + hit = undefined; + return hit; + } + const end = Date.now(); + const timing = (debug) ? `(${end - start} ms)` : ''; + // check for 'don't know' response from LLM and convert to no_hits behavior if pattern matches + const no_hits_regex = req._settings.LLM_QA_NO_HITS_REGEX || `Sorry, I don't know`; + const no_hits_res = answer.search(new RegExp(no_hits_regex, 'g')); + if (no_hits_res < 0) { + let llm_qa_prefix = ""; + if(req._settings.LLM_QA_PREFIX_MESSAGE){ + llm_qa_prefix = `${req._settings.LLM_QA_PREFIX_MESSAGE} ${timing}` ; } - }; - const body = JSON.stringify(data); - let smres = await sm.invokeEndpoint({ - EndpointName:sm_endpoint, - ContentType:'application/json', - Body:body, - }).promise(); - const sm_body = JSON.parse(Buffer.from(smres.Body, 'utf-8').toString()); - qnabot.log("Sagemaker QA response:", sm_body); - const sm_score = sm_body.score; - const sm_answer = sm_body.answer.trim(); - if (sm_score >= sm_confidence_threshold) { - qnabot.log(`Sagemaker QA response confidence score ${sm_score} meets threshold ${sm_confidence_threshold}`); - // prepend sm answer to plaintext and markdown - hit.a = `${sagemaker_qa_prefix} (Confidence: ${sm_score.toFixed(3)})\n\n${sm_answer}\n\n${hit.a}`; - hit.alt.markdown = `*${sagemaker_qa_prefix} (Confidence: ${sm_score.toFixed(3)})*\n\n**${sm_answer}**\n\n${hit.alt.markdown}`; - // replace ssml with just the short answer for concise voice responses - hit.alt.ssml = sm_answer; - qnabot.log("modified hit:", JSON.stringify(hit)); + + hit = prepend_llm_qa_answer(llm_qa_prefix, answer, hit); + hit.debug.push(`LLM: ${req._settings.LLM_API}`); } else { + qnabot.log(`No Hits pattern returned by LLM: "${no_hits_regex}"`); hit = undefined; - qnabot.log(`Sagemaker QA response confidence score ${sm_score} does not meets threshold ${sm_confidence_threshold}. Kendra response not used.`); } + return hit; } @@ -258,7 +283,7 @@ async function get_hit(req, res) { var hit = _.get(response, 'hits.hits[0]._source'); _.set(res, 'kendraResultsCached', response.kendraResultsCached); - if (response.kendraResultsCached) qnabot.log('kendra results cached in res structure'); + if (response.kendraResultsCached) qnabot.debug('kendra results cached in res structure'); _.set(req, 'session.qnabotcontext.kendra', response.kendra_context); if (response.kendra_context) qnabot.log('kendra context set in res session'); @@ -311,45 +336,56 @@ async function get_hit(req, res) { if (hit) { res['got_hits'] = 1; // response flag, used in logging / kibana - } else if(query_params.kendra_indexes.length != 0) { - qnabot.log('request entering kendra fallback ' + JSON.stringify(req)); - hit = await kendra_fallback.handler({req,res}); - qnabot.log('Result from Kendra ' + JSON.stringify(hit)); - if(hit && hit.hit_count != 0) - { - // Optionally post-process Kendra result with Sagemaker hosted Question_Answer model - const sm_endpoint = _.get(req, '_settings.KENDRA_FALLBACK_SAGEMAKER_QA_ENDPOINT'); - if (sm_endpoint) { - const sm_confidence_threshold = _.get(req, '_settings.KENDRA_FALLBACK_SAGEMAKER_QA_MIN_CONFIDENCE',0); - const sagemaker_qa_prefix = _.get(req, '_settings.KENDRA_FALLBACK_SAGEMAKER_QA_PREFIX', ""); - hit = await post_process_with_sagemaker_endpoint(req.question, hit, sagemaker_qa_prefix, sm_endpoint, sm_confidence_threshold); - } + if (! hit.debug) { + hit.debug=[]; } - if(hit && hit.hit_count != 0) - { - // Optionally try new experimental Lex CFAQ model - const cfaq_endpoint = _.get(req, '_settings.CFAQ_SAGEMAKER_ENDPOINT'); - if (cfaq_endpoint) { - const cfaq_domain = _.get(req, '_settings.CFAQ_DOMAIN'); - const cfaq_prefix = _.get(req, '_settings.CFAQ_PREFIX', ""); - const cfaq_index = _.get(req, '_settings.CFAQ_INDEX'); - const cfaq_n_ctx = _.get(req, '_settings.CFAQ_N_CONTEXT', 0); - hit = await prepend_cfaq_answer(req.question, hit, cfaq_prefix, cfaq_endpoint, cfaq_domain, cfaq_index, cfaq_n_ctx); + + if (hit.type === 'text') { + if (hit.passage && !hit.a) { + // Set the answer (a) field to match the text item passage field. + hit.a = hit.passage; + } + if (! _.get(hit, "alt.markdown")) { + _.set(hit, "alt.markdown", hit.a); } + if (! _.get(hit, "alt.ssml")) { + _.set(hit, "alt.ssml", hit.a); + } + // Run any configured QA Summary options on the text passage result + hit = await run_llm_qa(req, hit); + } + } else if(query_params.kendra_indexes.length != 0) { + // If enabled, try Kendra Retrieval API + if (req._settings.LLM_QA_ENABLE && req._settings.LLM_QA_USE_KENDRA_RETRIEVAL_API) { + qnabot.log('Kendra Fallback using Retrieve API: ' + JSON.stringify(req)); + hit = await kendra_retrieve.handler(req, res) + qnabot.log("Kendra Fallback result: ", JSON.stringify(hit, null, 2)); + } + //if we still don't have a hit, either retrieval was skipped or failed. Try the Query API + if(!hit){ + qnabot.log('Kendra Fallback using Query API: ' + JSON.stringify(req)); + hit = await kendra_fallback.handler({req,res}); + qnabot.log('Result from Kendra Fallback ' + JSON.stringify(hit)); } if(hit && hit.hit_count != 0) { - _.set(res,'answersource','Kendra Fallback'); - _.set(res,'session.qnabot_gotanswer',true) ; - _.set(res,'message', hit.a); - _.set(req,'debug',hit.debug) - res['got_hits'] = 1; + hit.refMarkdown = get_sourceLinks_from_passages(hit.alt.markdown); + // Run any configured QA Summary LLM model options on Kendra results + hit = await run_llm_qa(req, hit); + if (hit) { + _.set(res,'answersource','Kendra Fallback'); + _.set(res,'session.qnabot_gotanswer',true) ; + _.set(res,'message', hit.a); + _.set(req,'debug',hit.debug) + res['got_hits'] = 1; + } } } if(!hit) { qnabot.log('No hits from query - searching instead for: ' + no_hits_question); query_params['question'] = no_hits_question; + query_params['score_text_passage'] = false; query_params['size'] = 1; res['got_hits'] = 0; // response flag, used in logging / kibana response = await run_query(req, query_params); @@ -416,7 +452,15 @@ async function get_hit(req, res) { return [req, res, hit]; } - +function isQidQuery(req) { + if (req.question.toLowerCase().startsWith("qid::")) { + return true; + } + if (_.get(req, 'qid')) { + return true; + } + return false; +} /** * Central location to evaluate conditional chaining. Chaining can take place either when an elicitResponse is @@ -458,15 +502,11 @@ async function evaluateConditionalChaining(req, res, hit, conditionalChaining) { } } else { // create chaining rule safeEval context, aligned with Handlebars context - const SessionAttributes = (arg) => _.get(SessionAttributes, arg, undefined); - _.assign(SessionAttributes, res.session); - const Slots = (arg) => _.get(Slots, arg, undefined); - _.assign(Slots, req.slots); const sandbox={ LexOrAlexa: req._type, UserInfo:req._userInfo, - SessionAttributes, - Slots, + SessionAttributes: res.session, + Slots: req.slots, Settings: req._settings, Question: req.question, OrigQuestion: _.get(req,'_event.origQuestion',req.question), @@ -474,9 +514,10 @@ async function evaluateConditionalChaining(req, res, hit, conditionalChaining) { Sentiment: req.sentiment, }; qnabot.log('Evaluating:', conditionalChaining); + qnabot.debug('Sandbox:', JSON.stringify(sandbox, null, 2)); // safely evaluate conditionalChaining expression.. throws an exception if there is a syntax error - const vm = new VM({sandbox}); - next_q = vm.run(conditionalChaining, sandbox); + const ast = esprimaParse(conditionalChaining).body[0].expression; + next_q = staticEval(ast, sandbox) } qnabot.log('Chained document rule evaluated to:', next_q); req.question = next_q; @@ -615,6 +656,11 @@ function update_res_with_hit(req, res, hit) { async function processFulfillmentEvent(req,res) { qnabot.log('Process Fulfillment Code Hook event'); + // reset chatMemoryHistory if this is a new session... + if (_.get(res,'session.qnabotcontext.previous') == undefined) { + qnabot.log("New chat session - qnabotcontext is empty. Reset previous chatMemoryHistory"); + req._userInfo.chatMessageHistory = "[]"; + } const elicitResponseChainingConfig = _.get(res, 'session.qnabotcontext.elicitResponse.chainingConfig', undefined); const elicitResponseProgress = _.get(res, 'session.qnabotcontext.elicitResponse.progress', undefined); let hit = undefined; @@ -626,10 +672,17 @@ async function processFulfillmentEvent(req,res) { [req, res, hit] = await evaluateConditionalChaining(req, res, fakeHit, elicitResponseChainingConfig); } else { // elicitResponse is not involved. obtain the next question to serve up to the user. + if (req._settings.LLM_GENERATE_QUERY_ENABLE) { + if (! isQidQuery(req)) { + req = await llm.generate_query(req); + } else { + qnabot.debug("QID specified in query - do not generate LLM query."); + } + } [req, res, hit] = await get_hit(req, res); } if (hit) { - // found a document in elastic search. + // found a result. var c=0; while (_.get(hit, 'conditionalChaining') && _.get(hit, 'elicitResponse.responsebot_hook', '') === '' ) { c++; @@ -642,6 +695,17 @@ async function processFulfillmentEvent(req,res) { break ; } } + // update conversation memory in userInfo (will be automatically persisted later to DynamoDB userinfo table) + const chatMessageHistory = await llm.chatMemoryParse(_.get(req._userInfo, "chatMessageHistory","[]"), req._settings.LLM_CHAT_HISTORY_MAX_MESSAGES); + chatMessageHistory.addUserMessage(llm.get_question(req)); + let aiMessage = hit.a || ""; + // remove prefix message and timing debug info, if any, before storing message + if(req._settings.LLM_QA_PREFIX_MESSAGE){ + aiMessage = aiMessage.replace(new RegExp(req._settings.LLM_QA_PREFIX_MESSAGE + "\\s*(\\(.*?\\))*", 'g'), '').trim(); + } + chatMessageHistory.addAIChatMessage(aiMessage || ""); + res._userInfo.chatMessageHistory = await llm.chatMemorySerialise(chatMessageHistory, req._settings.LLM_CHAT_HISTORY_MAX_MESSAGES); + // translate response var usrLang = 'en'; const autotranslate = _.get(hit, 'autotranslate', true); @@ -656,17 +720,39 @@ async function processFulfillmentEvent(req,res) { } } // prepend debug msg - qnabot.debug('pre-debug ' +JSON.stringify(req)) if (_.get(req._settings, 'ENABLE_DEBUG_RESPONSES')) { - var msg = 'User Input: "' + req.question + '"'; - let qid = _.get(req, 'qid'); - if (usrLang != 'en') { - msg = 'User Input: "' + _.get(req,'_event.origQuestion','notdefined') + '", Translated to: "' + req.question + '"'; + let original_input, translated_input, llm_generated_query; + if (req.llm_generated_query) { + if (usrLang != 'en') { + original_input = _.get(req,'_event.origQuestion','notdefined'); + const translated_input = req.llm_generated_query.orig; + const llm_generated_query = req.llm_generated_query.result; + const search_string = req.llm_generated_query.concatenated; + const timing = req.llm_generated_query.timing; + msg = `User Input: "${original_input}", Translated to: "${translated_input}", LLM generated query (${timing}): "${llm_generated_query}", Search string: "${search_string}"` + } else { + original_input = req.llm_generated_query.orig; + llm_generated_query = req.llm_generated_query.result; + const search_string = req.llm_generated_query.concatenated; + const timing = req.llm_generated_query.timing; + msg = `User Input: "${original_input}", LLM generated query (${timing}): "${llm_generated_query}", Search string: "${search_string}"`; + } + } else { + if (usrLang != 'en') { + original_input = _.get(req,'_event.origQuestion','notdefined'); + translated_input = req.question; + msg = `User Input: "${original_input}", Translated to: "${translated_input}"`; + } else { + original_input = req.question; + msg = `User Input: "${original_input}"`; + } } + + let qid = _.get(req, 'qid'); if (qid) { msg += ', Lex Intent matched QID "' + qid + '"' ; } - if(req.debug) + if(req.debug && req.debug.length) { msg += JSON.stringify(req.debug,2) } @@ -718,7 +804,7 @@ function process_slots(req, res, hit) { if (!slotValue) { if (slotValueCached) { qnabot.log(`Slot value caching enabled for: '${slotName}' using session attribute '${slot_sessionAttrName}'`); - value = _.get(res.session, slot_sessionAttrName); + let value = _.get(res.session, slot_sessionAttrName); if (value) { qnabot.log(`Filling slot ${slotName} using cached value: ${value}`); _.set(res, `slots.${slotName}`, value); @@ -750,7 +836,7 @@ async function processDialogEvent(req, res) { // retrieve QID item that was mapped to intent let qid = _.get(req, 'qid'); if (qid) { - question = `QID::${qid}`; + let question = `QID::${qid}`; qnabot.log(`QID identified in request: ${qid}`) var query_params = { question: question, diff --git a/lambda/es-proxy-layer/package-lock.json b/lambda/es-proxy-layer/package-lock.json index 84a0dbb30..38b4fae78 100644 --- a/lambda/es-proxy-layer/package-lock.json +++ b/lambda/es-proxy-layer/package-lock.json @@ -1,58 +1,213 @@ { "name": "proxy-es", "version": "1.0.0", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "proxy-es", "version": "1.0.0", - "license": "ISC", + "license": "Apache-2.0", "dependencies": { "aws4": "^1.6.0", - "axios": "0.21.4", + "axios": "^0.26.0", "handlebars": "^4.7.2", + "langchain": "^0.0.63", "linkifyjs": "^3.0.0-beta.3", "simple-encryptor": "^3.0.0", - "vm2": "^3.9.18" + "static-eval": "^2.1.0" } }, - "node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" + "node_modules/@anthropic-ai/sdk": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.4.4.tgz", + "integrity": "sha512-Z/39nQi1sSUCeLII3lsAbL1u+0JF6cR2XmUEX9sLH0VtxmIjY6cjOUYjCkYh4oapTxOkhAFnVSAFJ6cxml2qXg==", + "dependencies": { + "@fortaine/fetch-event-source": "^3.0.6", + "cross-fetch": "^3.1.5" } }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "node_modules/@dqbd/tiktoken": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@dqbd/tiktoken/-/tiktoken-1.0.7.tgz", + "integrity": "sha512-bhR5k5W+8GLzysjk8zTMVygQZsgvf7W1F0IlL4ZQ5ugjo5rCyiwGM5d8DYriXspytfu98tv59niang3/T+FoDw==" + }, + "node_modules/@fortaine/fetch-event-source": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@fortaine/fetch-event-source/-/fetch-event-source-3.0.6.tgz", + "integrity": "sha512-621GAuLMvKtyZQ3IA6nlDWhV1V/7PGOTNIGLUifxt0KzM+dZIweJ6F3XvQF3QnqeNfS1N7WQ0Kil1Di/lhChEw==", "engines": { - "node": ">=0.4.0" + "node": ">=16.15" } }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" }, "node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", "dependencies": { - "follow-redirects": "^1.14.0" + "follow-redirects": "^1.14.8" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/binary-search": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/binary-search/-/binary-search-1.3.6.tgz", + "integrity": "sha512-nbE1WxOTTrUWIfsfZ4aHGYu5DOuNkbxGokjV6Z2kxfJK3uaAb8zNK1muzOeipoLHZjInT4Br88BHpzevc681xA==" + }, + "node_modules/browser-or-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-2.1.1.tgz", + "integrity": "sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cross-fetch": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.6.tgz", + "integrity": "sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==", + "dependencies": { + "node-fetch": "^2.6.11" + } + }, + "node_modules/cross-fetch/node_modules/node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/expr-eval": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expr-eval/-/expr-eval-2.0.2.tgz", + "integrity": "sha512-4EMSHGOPSwAfBiibw3ndnP0AvjDWLsMvGOvWEZ2F96IGk0bIVdjQisOHxReSkE13mHcfbuCiXw+G4y0zv6N8Eg==" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "bin": { + "flat": "cli.js" } }, "node_modules/follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", "funding": [ { "type": "individual", @@ -68,6 +223,19 @@ } } }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/handlebars": { "version": "4.7.7", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", @@ -88,91 +256,352 @@ "uglify-js": "^3.1.4" } }, - "node_modules/jquery": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz", - "integrity": "sha512-opJeO4nCucVnsjiXOE+/PcCgYw9Gwpvs/a6B1LL/lQhwWwpbVEVYDZ1FokFr8PRc7ghYlrFPuyHuiiDNTQxmcw==", - "peer": true + "node_modules/is-any-array": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-any-array/-/is-any-array-2.0.1.tgz", + "integrity": "sha512-UtilS7hLRu++wb/WBAw9bNuP1Eg04Ivn1vERJck8zJthEvXCBEBpGR/33u/xLKWEQf95803oalHrVDptcAvFdQ==" }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "peer": true + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/linkifyjs": { - "version": "3.0.0-beta.3", - "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-3.0.0-beta.3.tgz", - "integrity": "sha512-aXq4WJs91NsETo5f9dQrt8Vx+OxAvzJAtR8lLgpum8PDjtCgstycwYbIkAjDGRV/YF1LlKKdbWyOpgMYgwgOvQ==", + "node_modules/langchain": { + "version": "0.0.63", + "resolved": "https://registry.npmjs.org/langchain/-/langchain-0.0.63.tgz", + "integrity": "sha512-iC1qOJU5UT+GWSNH35dtmP1O5DxgK+rAdXtjTsi5Oi4+mo2k/cU2GMJGvPy4WaucdbvduLSWLw7l/tuUVqCtkg==", + "dependencies": { + "@anthropic-ai/sdk": "^0.4.3", + "@dqbd/tiktoken": "^1.0.4", + "binary-extensions": "^2.2.0", + "browser-or-node": "^2.1.1", + "expr-eval": "^2.0.2", + "flat": "^5.0.2", + "jsonpointer": "^5.0.1", + "ml-distance": "^4.0.0", + "object-hash": "^3.0.0", + "openai": "^3.2.0", + "p-queue": "^6.6.2", + "p-retry": "4", + "uuid": "^9.0.0", + "yaml": "^2.2.1", + "zod": "^3.21.4", + "zod-to-json-schema": "^3.20.4" + }, "engines": { - "node": ">=8" + "node": ">=18" }, "peerDependencies": { - "jquery": ">= 1.11.0", - "react": ">= 0.14.0", - "react-dom": ">= 0.14.0" + "@aws-sdk/client-lambda": "^3.310.0", + "@aws-sdk/client-s3": "^3.310.0", + "@getmetal/metal-sdk": "*", + "@huggingface/inference": "^1.5.1", + "@opensearch-project/opensearch": "*", + "@pinecone-database/pinecone": "*", + "@supabase/supabase-js": "^2.10.0", + "@zilliz/milvus2-sdk-node": "^2.2.0", + "axios": "^0.26.0", + "cheerio": "^1.0.0-rc.12", + "chromadb": "^1.4.0", + "cohere-ai": "^5.0.2", + "d3-dsv": "^2.0.0", + "epub2": "^3.0.1", + "hnswlib-node": "^1.4.2", + "html-to-text": "^9.0.5", + "mammoth": "*", + "mongodb": "^5.2.0", + "pdf-parse": "1.1.1", + "playwright": "^1.32.1", + "puppeteer": "^19.7.2", + "redis": "^4.6.4", + "replicate": "^0.9.0", + "srt-parser-2": "^1.2.2", + "typeorm": "^0.3.12", + "weaviate-ts-client": "^1.0.0" + }, + "peerDependenciesMeta": { + "@aws-sdk/client-lambda": { + "optional": true + }, + "@aws-sdk/client-s3": { + "optional": true + }, + "@getmetal/metal-sdk": { + "optional": true + }, + "@huggingface/inference": { + "optional": true + }, + "@opensearch-project/opensearch": { + "optional": true + }, + "@pinecone-database/pinecone": { + "optional": true + }, + "@supabase/supabase-js": { + "optional": true + }, + "@zilliz/milvus2-sdk-node": { + "optional": true + }, + "axios": { + "optional": true + }, + "cheerio": { + "optional": true + }, + "chromadb": { + "optional": true + }, + "cohere-ai": { + "optional": true + }, + "d3-dsv": { + "optional": true + }, + "epub2": { + "optional": true + }, + "hnswlib-node": { + "optional": true + }, + "html-to-text": { + "optional": true + }, + "mammoth": { + "optional": true + }, + "mongodb": { + "optional": true + }, + "pdf-parse": { + "optional": true + }, + "playwright": { + "optional": true + }, + "puppeteer": { + "optional": true + }, + "redis": { + "optional": true + }, + "replicate": { + "optional": true + }, + "srt-parser-2": { + "optional": true + }, + "typeorm": { + "optional": true + }, + "weaviate-ts-client": { + "optional": true + } } }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "peer": true, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" }, - "bin": { - "loose-envify": "cli.js" + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/linkifyjs": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-3.0.5.tgz", + "integrity": "sha512-1Y9XQH65eQKA9p2xtk+zxvnTeQBG7rdAXSkUG97DmuI/Xhji9uaUzaWxRj6rf9YC0v8KKHkxav7tnLX82Sz5Fg==" + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" } }, "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ml-array-mean": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/ml-array-mean/-/ml-array-mean-1.1.6.tgz", + "integrity": "sha512-MIdf7Zc8HznwIisyiJGRH9tRigg3Yf4FldW8DxKxpCCv/g5CafTw0RRu51nojVEOXuCQC7DRVVu5c7XXO/5joQ==", + "dependencies": { + "ml-array-sum": "^1.1.6" + } + }, + "node_modules/ml-array-sum": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/ml-array-sum/-/ml-array-sum-1.1.6.tgz", + "integrity": "sha512-29mAh2GwH7ZmiRnup4UyibQZB9+ZLyMShvt4cH4eTK+cL2oEMIZFnSyB3SS8MlsTh6q/w/yh48KmqLxmovN4Dw==", + "dependencies": { + "is-any-array": "^2.0.0" + } + }, + "node_modules/ml-distance": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/ml-distance/-/ml-distance-4.0.1.tgz", + "integrity": "sha512-feZ5ziXs01zhyFUUUeZV5hwc0f5JW0Sh0ckU1koZe/wdVkJdGxcP06KNQuF0WBTj8FttQUzcvQcpcrOp/XrlEw==", + "dependencies": { + "ml-array-mean": "^1.1.6", + "ml-distance-euclidean": "^2.0.0", + "ml-tree-similarity": "^1.0.0" + } + }, + "node_modules/ml-distance-euclidean": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ml-distance-euclidean/-/ml-distance-euclidean-2.0.0.tgz", + "integrity": "sha512-yC9/2o8QF0A3m/0IXqCTXCzz2pNEzvmcE/9HFKOZGnTjatvBbsn4lWYJkxENkA4Ug2fnYl7PXQxnPi21sgMy/Q==" + }, + "node_modules/ml-tree-similarity": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ml-tree-similarity/-/ml-tree-similarity-1.0.0.tgz", + "integrity": "sha512-XJUyYqjSuUQkNQHMscr6tcjldsOoAekxADTplt40QKfwW6nd++1wHWV9AArl0Zvw/TIHgNaZZNvr8QGvE8wLRg==", + "dependencies": { + "binary-search": "^1.3.5", + "num-sort": "^2.0.0" + } }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, - "node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "peer": true, + "node_modules/num-sort": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/num-sort/-/num-sort-2.1.0.tgz", + "integrity": "sha512-1MQz1Ed8z2yckoBeSfkQHHO9K1yDRxxtotKSJ9yvcTUUxSvfvzEq5GwBrjjHEpMlq/k5gvXdmJ1SbYxWtpNoVg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/openai": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-3.3.0.tgz", + "integrity": "sha512-uqxI/Au+aPRnsaQRe8CojU0eCR7I0mBiKjD3sNMzY6DaC1ZVrc85u98mtJW6voDug8fgGN+DIZmTDxTthxb7dQ==", "dependencies": { - "loose-envify": "^1.1.0" + "axios": "^0.26.0", + "form-data": "^4.0.0" + } + }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8.0" } }, - "node_modules/react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "peer": true, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" }, - "peerDependencies": { - "react": "^18.2.0" + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", - "peer": true, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", "dependencies": { - "loose-envify": "^1.1.0" + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "engines": { + "node": ">= 4" } }, "node_modules/scmp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/scmp/-/scmp-2.0.0.tgz", - "integrity": "sha1-JHEQ7yLM+JexOj8KvdtSeCOTzWo=" + "integrity": "sha512-FaHoAk75AYhT+rnBmMpkvHSIcQma4OHzYXOhn1XXtgNomi0FTV8YEXYuh2EIdCg5IKMVyFbXeJT4Cn96+fzABg==" }, "node_modules/simple-encryptor": { "version": "3.0.0", @@ -193,10 +622,34 @@ "node": ">=0.10.0" } }, + "node_modules/static-eval": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.1.0.tgz", + "integrity": "sha512-agtxZ/kWSsCkI5E4QifRwsaPs0P0JmZV6dkLz6ILYfFYQGn+5plctanRN+IC8dJRiFkyXHrwEE3W9Wmx67uDbw==", + "dependencies": { + "escodegen": "^1.11.1" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/uglify-js": { - "version": "3.13.9", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.9.tgz", - "integrity": "sha512-wZbyTQ1w6Y7fHdt8sJnHfSIuWeDgk6B5rCb4E/AM6QNNPbOMIZph21PW5dRB3h7Df0GszN+t7RuUH6sWK5bF0g==", + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", "optional": true, "bin": { "uglifyjs": "bin/uglifyjs" @@ -205,170 +658,64 @@ "node": ">=0.8.0" } }, - "node_modules/vm2": { - "version": "3.9.19", - "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.19.tgz", - "integrity": "sha512-J637XF0DHDMV57R6JyVsTak7nIL8gy5KH4r1HiwWLf/4GBbb5MKL5y7LpmF4A8E2nR6XmzpmMFQ7V7ppPTmUQg==", - "dependencies": { - "acorn": "^8.7.0", - "acorn-walk": "^8.2.0" - }, + "node_modules/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", "bin": { - "vm2": "bin/vm2" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" - } - }, - "dependencies": { - "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==" - }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" - }, - "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "requires": { - "follow-redirects": "^1.14.0" - } - }, - "follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==" - }, - "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" + "uuid": "dist/bin/uuid" } }, - "jquery": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz", - "integrity": "sha512-opJeO4nCucVnsjiXOE+/PcCgYw9Gwpvs/a6B1LL/lQhwWwpbVEVYDZ1FokFr8PRc7ghYlrFPuyHuiiDNTQxmcw==", - "peer": true + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "peer": true - }, - "linkifyjs": { - "version": "3.0.0-beta.3", - "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-3.0.0-beta.3.tgz", - "integrity": "sha512-aXq4WJs91NsETo5f9dQrt8Vx+OxAvzJAtR8lLgpum8PDjtCgstycwYbIkAjDGRV/YF1LlKKdbWyOpgMYgwgOvQ==", - "requires": {} - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "peer": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "peer": true, - "requires": { - "loose-envify": "^1.1.0" - } - }, - "react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "peer": true, - "requires": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" } }, - "scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", - "peer": true, - "requires": { - "loose-envify": "^1.1.0" + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "engines": { + "node": ">=0.10.0" } }, - "scmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/scmp/-/scmp-2.0.0.tgz", - "integrity": "sha1-JHEQ7yLM+JexOj8KvdtSeCOTzWo=" + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" }, - "simple-encryptor": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/simple-encryptor/-/simple-encryptor-3.0.0.tgz", - "integrity": "sha512-xRgj9pU3Gfkl+6iBYRoXM4BdEwY4bLdL1W0tp7AjGTA7Hytv5iwmB5tvJh6K2iVszvPPYimQjLFV8jRZz3fJ1g==", - "requires": { - "scmp": "2.0.0" + "node_modules/yaml": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", + "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", + "engines": { + "node": ">= 14" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "uglify-js": { - "version": "3.13.9", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.9.tgz", - "integrity": "sha512-wZbyTQ1w6Y7fHdt8sJnHfSIuWeDgk6B5rCb4E/AM6QNNPbOMIZph21PW5dRB3h7Df0GszN+t7RuUH6sWK5bF0g==", - "optional": true - }, - "vm2": { - "version": "3.9.19", - "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.19.tgz", - "integrity": "sha512-J637XF0DHDMV57R6JyVsTak7nIL8gy5KH4r1HiwWLf/4GBbb5MKL5y7LpmF4A8E2nR6XmzpmMFQ7V7ppPTmUQg==", - "requires": { - "acorn": "^8.7.0", - "acorn-walk": "^8.2.0" + "node_modules/zod": { + "version": "3.21.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz", + "integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" } }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + "node_modules/zod-to-json-schema": { + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.21.1.tgz", + "integrity": "sha512-y5g0MPxDq+YG/T+cHGPYH4PcBpyCqwK6wxeJ76MR563y0gk/14HKfebq8xHiItY7lkc9GDFygCnkvNDTvAhYAg==", + "peerDependencies": { + "zod": "^3.21.4" + } } } } diff --git a/lambda/es-proxy-layer/package.json b/lambda/es-proxy-layer/package.json index 09fda19ad..be9312825 100644 --- a/lambda/es-proxy-layer/package.json +++ b/lambda/es-proxy-layer/package.json @@ -3,14 +3,18 @@ "version": "1.0.0", "description": "", "main": "index.js", - "author": "", - "license": "ISC", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com/solutions" + }, + "license": "Apache-2.0", "dependencies": { "aws4": "^1.6.0", - "axios": "0.21.4", + "axios": "^0.26.0", "handlebars": "^4.7.2", + "langchain": "^0.0.63", "linkifyjs": "^3.0.0-beta.3", "simple-encryptor": "^3.0.0", - "vm2": "^3.9.18" + "static-eval": "^2.1.0" } } diff --git a/lambda/export/lib/load.js b/lambda/export/lib/load.js index b6557ed85..61a7a126c 100644 --- a/lambda/export/lib/load.js +++ b/lambda/export/lib/load.js @@ -22,15 +22,19 @@ module.exports=function(config,body){ const documents=_.get(result,"hits.hits",[]) if(documents.length){ const body=documents.map(x=>{ - const out=x._source - if(out.type==='qna' && _.has(out,"questions")){ - out.q=out.questions.map(y=>y.q) - delete out.questions - delete out.quniqueterms; - }else{ - out._id=x._id; + const out = x._source; + // remap nested questions array for JSON file backward compatability + if (out.type === 'qna' && _.has(out, 'questions')) { + out.q = out.questions.map((y) => y.q); } - return JSON.stringify(out) + // if item has a qid, we don;t need the _id field, so we can delete it. + if (!_.has(out, 'qid')) { + out._id = x._id; + } + // delete fields that we don't need in the exported JSON + delete out.questions; + delete out.quniqueterms; + return JSON.stringify(out); }).join('\n') const key=`${config.tmp}/${config.parts.length+1}` return s3.putObject({ diff --git a/lambda/export/lib/start.js b/lambda/export/lib/start.js index c4c2db1ea..af14bcf31 100644 --- a/lambda/export/lib/start.js +++ b/lambda/export/lib/start.js @@ -26,7 +26,7 @@ function query(filter){ return { size:1000, _source: { - "exclude": ["questions.q_vector", "a_vector"] + "exclude": ["questions.q_vector", "a_vector", "passage_vector"] }, query:{ bool:_.pickBy({ diff --git a/lambda/export/package-lock.json b/lambda/export/package-lock.json index d205e6125..32cadf568 100644 --- a/lambda/export/package-lock.json +++ b/lambda/export/package-lock.json @@ -7,837 +7,33 @@ "": { "name": "import", "version": "1.0.0", - "license": "ISC", + "license": "Apache-2.0", "dependencies": { - "aws-sdk": "^2.1354.0", "bluebird": "^3.5.1", - "csv-parser": "^2.3.3", - "csv-writer": "^1.6.0", - "install": "^0.13.0", - "intercept-stdout": "^0.1.2", - "lodash": "^4.17.21", - "save-dev": "0.0.1-security" + "lodash": "^4.17.21" } }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/aws-sdk": { - "version": "2.1354.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1354.0.tgz", - "integrity": "sha512-3aDxvyuOqMB9DqJguCq6p8momdsz0JR1axwkWOOCzHA7a35+Bw+WLmqt3pWwRjR1tGIwkkZ2CvGJObYHsOuw3w==", - "dependencies": { - "buffer": "4.9.2", - "events": "1.1.1", - "ieee754": "1.1.13", - "jmespath": "0.16.0", - "querystring": "0.2.0", - "sax": "1.2.1", - "url": "0.10.3", - "util": "^0.12.4", - "uuid": "8.0.0", - "xml2js": "0.5.0" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" - }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, - "node_modules/buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "node_modules/buffer/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/csv-parser": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/csv-parser/-/csv-parser-2.3.3.tgz", - "integrity": "sha512-czcyxc4/3Tt63w0oiK1zsnRgRD4PkqWaRSJ6eef63xC0f+5LVLuGdSYEcJwGp2euPgRHx+jmlH2Lb49anb1CGQ==", - "dependencies": { - "minimist": "^1.2.0", - "through2": "^3.0.1" - }, - "bin": { - "csv-parser": "bin/csv-parser" - }, - "engines": { - "node": ">= 8.16.0" - } - }, - "node_modules/csv-writer": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/csv-writer/-/csv-writer-1.6.0.tgz", - "integrity": "sha512-NOx7YDFWEsM/fTRAJjRpPp8t+MKRVvniAg9wQlUKx20MFrPs73WLJhFf5iteqrxNYnsy924K3Iroh3yNHeYd2g==" - }, - "node_modules/events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/install": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz", - "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/intercept-stdout": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/intercept-stdout/-/intercept-stdout-0.1.2.tgz", - "integrity": "sha1-Emq/H65sUJpCipjGGmMVWQQq6f0=", - "dependencies": { - "lodash.toarray": "^3.0.0" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/jmespath": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", - "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash._arraycopy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz", - "integrity": "sha1-due3wfH7klRzdIeKVi7Qaj5Q9uE=" - }, - "node_modules/lodash._basevalues": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", - "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=" - }, - "node_modules/lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" - }, - "node_modules/lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" - }, - "node_modules/lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" - }, - "node_modules/lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "dependencies": { - "lodash._getnative": "^3.0.0", - "lodash.isarguments": "^3.0.0", - "lodash.isarray": "^3.0.0" - } - }, - "node_modules/lodash.toarray": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-3.0.2.tgz", - "integrity": "sha1-KyBPD6T1HChcbwDIHRzqWiMEEXk=", - "dependencies": { - "lodash._arraycopy": "^3.0.0", - "lodash._basevalues": "^3.0.0", - "lodash.keys": "^3.0.0" - } - }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" - }, - "node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - }, - "node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/save-dev": { - "version": "0.0.1-security", - "resolved": "https://registry.npmjs.org/save-dev/-/save-dev-0.0.1-security.tgz", - "integrity": "sha512-k6knZTDNK8PKKbIqnvxiOveJinuw2LcQjqDoaorZWP9M5AR2EPsnpDeSbeoZZ0pHr5ze1uoaKdK8NBGQrJ34Uw==" - }, - "node_modules/sax": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - }, - "node_modules/url": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", - "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/uuid": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", - "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/xml2js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "engines": { - "node": ">=4.0" - } } }, "dependencies": { - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" - }, - "aws-sdk": { - "version": "2.1354.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1354.0.tgz", - "integrity": "sha512-3aDxvyuOqMB9DqJguCq6p8momdsz0JR1axwkWOOCzHA7a35+Bw+WLmqt3pWwRjR1tGIwkkZ2CvGJObYHsOuw3w==", - "requires": { - "buffer": "4.9.2", - "events": "1.1.1", - "ieee754": "1.1.13", - "jmespath": "0.16.0", - "querystring": "0.2.0", - "sax": "1.2.1", - "url": "0.10.3", - "util": "^0.12.4", - "uuid": "8.0.0", - "xml2js": "0.5.0" - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" - }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "csv-parser": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/csv-parser/-/csv-parser-2.3.3.tgz", - "integrity": "sha512-czcyxc4/3Tt63w0oiK1zsnRgRD4PkqWaRSJ6eef63xC0f+5LVLuGdSYEcJwGp2euPgRHx+jmlH2Lb49anb1CGQ==", - "requires": { - "minimist": "^1.2.0", - "through2": "^3.0.1" - } - }, - "csv-writer": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/csv-writer/-/csv-writer-1.6.0.tgz", - "integrity": "sha512-NOx7YDFWEsM/fTRAJjRpPp8t+MKRVvniAg9wQlUKx20MFrPs73WLJhFf5iteqrxNYnsy924K3Iroh3yNHeYd2g==" - }, - "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "requires": { - "is-callable": "^1.1.3" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "install": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz", - "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==" - }, - "intercept-stdout": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/intercept-stdout/-/intercept-stdout-0.1.2.tgz", - "integrity": "sha1-Emq/H65sUJpCipjGGmMVWQQq6f0=", - "requires": { - "lodash.toarray": "^3.0.0" - } - }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" - }, - "is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - } - }, - "jmespath": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", - "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==" - }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash._arraycopy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz", - "integrity": "sha1-due3wfH7klRzdIeKVi7Qaj5Q9uE=" - }, - "lodash._basevalues": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", - "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=" - }, - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" - }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" - }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" - }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "requires": { - "lodash._getnative": "^3.0.0", - "lodash.isarguments": "^3.0.0", - "lodash.isarray": "^3.0.0" - } - }, - "lodash.toarray": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-3.0.2.tgz", - "integrity": "sha1-KyBPD6T1HChcbwDIHRzqWiMEEXk=", - "requires": { - "lodash._arraycopy": "^3.0.0", - "lodash._basevalues": "^3.0.0", - "lodash.keys": "^3.0.0" - } - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" - }, - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "save-dev": { - "version": "0.0.1-security", - "resolved": "https://registry.npmjs.org/save-dev/-/save-dev-0.0.1-security.tgz", - "integrity": "sha512-k6knZTDNK8PKKbIqnvxiOveJinuw2LcQjqDoaorZWP9M5AR2EPsnpDeSbeoZZ0pHr5ze1uoaKdK8NBGQrJ34Uw==" - }, - "sax": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - }, - "url": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", - "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==" - }, - "which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - } - }, - "xml2js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - } - }, - "xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" } } } diff --git a/lambda/export/package.json b/lambda/export/package.json index 8030a1b65..33d4b0f9c 100644 --- a/lambda/export/package.json +++ b/lambda/export/package.json @@ -3,16 +3,13 @@ "version": "1.0.0", "description": "", "main": "index.js", - "author": "", - "license": "ISC", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com/solutions" + }, + "license": "Apache-2.0", "dependencies": { - "aws-sdk": "^2.1354.0", "bluebird": "^3.5.1", - "csv-parser": "^2.3.3", - "csv-writer": "^1.6.0", - "install": "^0.13.0", - "intercept-stdout": "^0.1.2", - "lodash": "^4.17.21", - "save-dev": "0.0.1-security" + "lodash": "^4.17.21" } } diff --git a/lambda/export/test/gen.js b/lambda/export/test/gen.js index e3911696a..ff8337859 100644 --- a/lambda/export/test/gen.js +++ b/lambda/export/test/gen.js @@ -1,5 +1,5 @@ #! /bin/env node -var config=require('../../../config') +var config=require('../../../config.json') process.env.AWS_PROFILE=config.profile process.env.AWS_DEFAULT_REGION=config.region diff --git a/lambda/export/test/index.js b/lambda/export/test/index.js index ef552a7c4..b5cddad59 100644 --- a/lambda/export/test/index.js +++ b/lambda/export/test/index.js @@ -1,4 +1,4 @@ -var config=require('../../../config') +var config=require('../../../config.json') process.env.STRIDE="10000" process.env.AWS_PROFILE=config.profile process.env.AWS_DEFAULT_REGION=config.region @@ -22,7 +22,7 @@ module.exports={ process.env.ES_PROXY=master.ESProxyLambda process.env.ES_TYPE=master.ElasticsearchType process.env.ES_INDEX=master.ElasticsearchIndex - + return handler.startAsync({ Records:[{ s3:{ @@ -39,7 +39,7 @@ module.exports={ bucket:{name:bucket} } }] - },null)) + },null)) .delay(1000) .then(()=>handler.stepAsync({ Records:[{ @@ -48,7 +48,7 @@ module.exports={ bucket:{name:bucket} } }] - },null)) + },null)) }) .catch(test.ifError) .finally(()=>test.done()) diff --git a/lambda/fulfillment/package-lock.json b/lambda/fulfillment/package-lock.json index 7dc047570..1b64c890f 100644 --- a/lambda/fulfillment/package-lock.json +++ b/lambda/fulfillment/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "fulfillment", "version": "1.0.0", - "license": "ISC", + "license": "Apache-2.0", "dependencies": { "jsonschema": "^1.2.2", "jsonwebtoken": "^9.0.0", @@ -531,9 +531,9 @@ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -1153,9 +1153,9 @@ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "requires": { "lru-cache": "^6.0.0" }, diff --git a/lambda/fulfillment/package.json b/lambda/fulfillment/package.json index ff52fe242..95679a1e6 100644 --- a/lambda/fulfillment/package.json +++ b/lambda/fulfillment/package.json @@ -7,8 +7,11 @@ "test": "nodeunit ./test/index.js", "unit": "nodeunit ./test/index.js -t" }, - "author": "", - "license": "ISC", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com/solutions" + }, + "license": "Apache-2.0", "dependencies": { "jsonschema": "^1.2.2", "jsonwebtoken": "^9.0.0", diff --git a/lambda/fulfillment/test/setup.js b/lambda/fulfillment/test/setup.js index 7d2a3750e..fda10f30e 100755 --- a/lambda/fulfillment/test/setup.js +++ b/lambda/fulfillment/test/setup.js @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 var Promise=require('bluebird') -var config=require('../../../config') +var config=require('../../../config.json') var aws=require('aws-sdk') var outputs=require('../../../bin/exports') const qnabot = require("qnabot/logging") diff --git a/lambda/fulfillment/test/setupenv.js b/lambda/fulfillment/test/setupenv.js index b4f04b63b..5e2189328 100755 --- a/lambda/fulfillment/test/setupenv.js +++ b/lambda/fulfillment/test/setupenv.js @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 var Promise=require('bluebird') -var config=require('../../../config') +var config=require('../../../config.json') var aws=require('aws-sdk') var outputs=require('../../../bin/exports') const qnabot = require("qnabot/logging") diff --git a/lambda/genesys/package-lock.json b/lambda/genesys/package-lock.json index ef7e80d9d..acc40a543 100644 --- a/lambda/genesys/package-lock.json +++ b/lambda/genesys/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "genesys", "version": "1.0.0", - "license": "SEE LICENSE IN LICENSE", + "license": "Apache-2.0", "devDependencies": { "jest": "^29.4.3" } diff --git a/lambda/genesys/package.json b/lambda/genesys/package.json index 3d2557d40..66f22cae3 100644 --- a/lambda/genesys/package.json +++ b/lambda/genesys/package.json @@ -19,7 +19,7 @@ "name": "Amazon Web Services", "url": "https://aws.amazon.com/solutions" }, - "license": "SEE LICENSE IN LICENSE", + "license": "Apache-2.0", "devDependencies": { "jest": "^29.4.3" } diff --git a/lambda/import/index.js b/lambda/import/index.js index 2f0abcd03..995e85269 100644 --- a/lambda/import/index.js +++ b/lambda/import/index.js @@ -110,9 +110,9 @@ exports.step = function (event, context, cb) { let timestamp = _.get(obj, 'datetime', ""); let docid; if (timestamp === "") { - // only metrics and feedback items have datetime field.. This must be a qna item. + // only metrics and feedback items have datetime field.. This must be a qna, quiz, or text item. obj.type = obj.type || 'qna' - if(obj.type != 'slottype') { + if(obj.type != 'slottype' && obj.type != 'text') { obj.q = obj.q.map(x => { x = x.replace(/\\*"/g, ''); return x @@ -144,6 +144,12 @@ exports.step = function (event, context, cb) { qnabot.log("skipping question due to exception", err); } delete obj.q + } else if (obj.type === 'text') { + // passage field embeddings + const passage = obj.passage; + if (passage) { + obj.passage_vector = await get_embeddings("a", passage, settings); + } } docid = obj._id || obj.qid; } else { diff --git a/lambda/import/package-lock.json b/lambda/import/package-lock.json index 899930499..2acced199 100644 --- a/lambda/import/package-lock.json +++ b/lambda/import/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "import", "version": "1.0.0", - "license": "ISC", + "license": "Apache-2.0", "dependencies": { "bluebird": "^3.5.1", "intercept-stdout": "^0.1.2", diff --git a/lambda/import/package.json b/lambda/import/package.json index cc8c665e7..fe2315b5d 100644 --- a/lambda/import/package.json +++ b/lambda/import/package.json @@ -6,8 +6,11 @@ "scripts": { "test": "nodeunit test.js" }, - "author": "", - "license": "ISC", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com/solutions" + }, + "license": "Apache-2.0", "dependencies": { "bluebird": "^3.5.1", "intercept-stdout": "^0.1.2", diff --git a/lambda/import/test/gen.js b/lambda/import/test/gen.js index e3911696a..ff8337859 100644 --- a/lambda/import/test/gen.js +++ b/lambda/import/test/gen.js @@ -1,5 +1,5 @@ #! /bin/env node -var config=require('../../../config') +var config=require('../../../config.json') process.env.AWS_PROFILE=config.profile process.env.AWS_DEFAULT_REGION=config.region diff --git a/lambda/import/test/index.js b/lambda/import/test/index.js index ef552a7c4..b5cddad59 100644 --- a/lambda/import/test/index.js +++ b/lambda/import/test/index.js @@ -1,4 +1,4 @@ -var config=require('../../../config') +var config=require('../../../config.json') process.env.STRIDE="10000" process.env.AWS_PROFILE=config.profile process.env.AWS_DEFAULT_REGION=config.region @@ -22,7 +22,7 @@ module.exports={ process.env.ES_PROXY=master.ESProxyLambda process.env.ES_TYPE=master.ElasticsearchType process.env.ES_INDEX=master.ElasticsearchIndex - + return handler.startAsync({ Records:[{ s3:{ @@ -39,7 +39,7 @@ module.exports={ bucket:{name:bucket} } }] - },null)) + },null)) .delay(1000) .then(()=>handler.stepAsync({ Records:[{ @@ -48,7 +48,7 @@ module.exports={ bucket:{name:bucket} } }] - },null)) + },null)) }) .catch(test.ifError) .finally(()=>test.done()) diff --git a/lambda/js_lambda_hook_sdk/package-lock.json b/lambda/js_lambda_hook_sdk/package-lock.json index 42d8be8cb..ae590fad8 100644 --- a/lambda/js_lambda_hook_sdk/package-lock.json +++ b/lambda/js_lambda_hook_sdk/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "js_lambda_hook_sdk", "version": "1.0.0", - "license": "SEE LICENSE IN LICENSE", + "license": "Apache-2.0", "dependencies": { "lodash": "^4.17.21" }, diff --git a/lambda/js_lambda_hook_sdk/package.json b/lambda/js_lambda_hook_sdk/package.json index fce0f024e..14d4815a3 100644 --- a/lambda/js_lambda_hook_sdk/package.json +++ b/lambda/js_lambda_hook_sdk/package.json @@ -14,7 +14,7 @@ "name": "Amazon Web Services", "url": "https://aws.amazon.com/solutions" }, - "license": "SEE LICENSE IN LICENSE", + "license": "Apache-2.0", "dependencies": { "lodash": "^4.17.21" }, diff --git a/lambda/lex-build/package-lock.json b/lambda/lex-build/package-lock.json index 22df83f27..cfd582f05 100644 --- a/lambda/lex-build/package-lock.json +++ b/lambda/lex-build/package-lock.json @@ -7,9 +7,8 @@ "": { "name": "lex-build", "version": "1.0.0", - "license": "ISC", + "license": "Apache-2.0", "dependencies": { - "aws-sdk": "^2.1354.0", "bluebird": "^3.7.2", "elasticsearch": "^16.7.1", "http-aws-es": "^6.0.0", @@ -47,69 +46,11 @@ "node": ">=0.10.0" } }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/aws-sdk": { - "version": "2.1354.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1354.0.tgz", - "integrity": "sha512-3aDxvyuOqMB9DqJguCq6p8momdsz0JR1axwkWOOCzHA7a35+Bw+WLmqt3pWwRjR1tGIwkkZ2CvGJObYHsOuw3w==", - "dependencies": { - "buffer": "4.9.2", - "events": "1.1.1", - "ieee754": "1.1.13", - "jmespath": "0.16.0", - "querystring": "0.2.0", - "sax": "1.2.1", - "url": "0.10.3", - "util": "^0.12.4", - "uuid": "8.0.0", - "xml2js": "0.5.0" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" - }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, - "node_modules/buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", @@ -155,62 +96,6 @@ "node": ">=0.8.0" } }, - "node_modules/events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -222,31 +107,6 @@ "node": ">=0.10.0" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/http-aws-es": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/http-aws-es/-/http-aws-es-6.0.0.tgz", @@ -260,16 +120,6 @@ "ms": "^2.0.0" } }, - "node_modules/ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, "node_modules/intercept-stdout": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/intercept-stdout/-/intercept-stdout-0.1.2.tgz", @@ -278,77 +128,6 @@ "lodash.toarray": "^3.0.0" } }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "node_modules/jmespath": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", - "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -404,24 +183,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - }, - "node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/sax": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" - }, "node_modules/strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -440,74 +201,6 @@ "engines": { "node": ">=0.8.0" } - }, - "node_modules/url": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", - "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/uuid": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", - "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/xml2js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "engines": { - "node": ">=4.0" - } } }, "dependencies": { @@ -529,57 +222,11 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" - }, - "aws-sdk": { - "version": "2.1354.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1354.0.tgz", - "integrity": "sha512-3aDxvyuOqMB9DqJguCq6p8momdsz0JR1axwkWOOCzHA7a35+Bw+WLmqt3pWwRjR1tGIwkkZ2CvGJObYHsOuw3w==", - "requires": { - "buffer": "4.9.2", - "events": "1.1.1", - "ieee754": "1.1.13", - "jmespath": "0.16.0", - "querystring": "0.2.0", - "sax": "1.2.1", - "url": "0.10.3", - "util": "^0.12.4", - "uuid": "8.0.0", - "xml2js": "0.5.0" - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" - }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", @@ -613,50 +260,6 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, - "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "requires": { - "is-callable": "^1.1.3" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -665,19 +268,6 @@ "ansi-regex": "^2.0.0" } }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "requires": { - "has-symbols": "^1.0.2" - } - }, "http-aws-es": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/http-aws-es/-/http-aws-es-6.0.0.tgz", @@ -691,16 +281,6 @@ "ms": "^2.0.0" } }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, "intercept-stdout": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/intercept-stdout/-/intercept-stdout-0.1.2.tgz", @@ -709,50 +289,6 @@ "lodash.toarray": "^3.0.0" } }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" - }, - "is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "jmespath": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", - "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==" - }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -808,21 +344,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" - }, - "sax": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -835,59 +356,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - }, - "url": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "uuid": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", - "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==" - }, - "which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - } - }, - "xml2js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - } - }, - "xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" } } } diff --git a/lambda/lex-build/package.json b/lambda/lex-build/package.json index 4df82b151..1ba59c558 100644 --- a/lambda/lex-build/package.json +++ b/lambda/lex-build/package.json @@ -7,10 +7,12 @@ "test": "nodeunit ./test/index.js", "unit": "nodeunit ./test/index.js -t" }, - "author": "", - "license": "ISC", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com/solutions" + }, + "license": "Apache-2.0", "dependencies": { - "aws-sdk": "^2.1354.0", "bluebird": "^3.7.2", "elasticsearch": "^16.7.1", "http-aws-es": "^6.0.0", diff --git a/lambda/lex-build/test/setup.js b/lambda/lex-build/test/setup.js index e90ed485e..f8d4e537d 100755 --- a/lambda/lex-build/test/setup.js +++ b/lambda/lex-build/test/setup.js @@ -1,7 +1,7 @@ #! /usr/bin/env node process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; var Promise=require('bluebird') -var config=require('../../../config') +var config=require('../../../config.json') var fs=Promise.promisifyAll(require('fs')) var aws=require('aws-sdk') @@ -14,7 +14,7 @@ module.exports=Promise.method(async function(event){ process.env.AWS_ACCESS_KEY_ID=aws.config.credentials.accessKeyId process.env.AWS_SECRET_ACCESS_KEY=aws.config.credentials.secretAccessKey process.env.AWS_REGION=config.region - + process.env.SALT='salt' var envs=await outputs('dev/bucket',{wait:true}) process.env.UTTERANCE_BUCKET=envs.Bucket diff --git a/lambda/proxy-es/package-lock.json b/lambda/proxy-es/package-lock.json index 5654cc919..2d8e87dc0 100644 --- a/lambda/proxy-es/package-lock.json +++ b/lambda/proxy-es/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "proxy-es", "version": "1.0.0", - "license": "SEE LICENSE IN LICENSE" + "license": "Apache-2.0" } } } diff --git a/lambda/proxy-es/package.json b/lambda/proxy-es/package.json index 418656d3b..54712da68 100644 --- a/lambda/proxy-es/package.json +++ b/lambda/proxy-es/package.json @@ -3,6 +3,9 @@ "version": "1.0.0", "description": "", "main": "index.js", - "author": "", - "license": "SEE LICENSE IN LICENSE" + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com/solutions" + }, + "license": "Apache-2.0" } diff --git a/lambda/qnabot-common-layer/package-lock.json b/lambda/qnabot-common-layer/package-lock.json index 2a116a0ab..e22f06e83 100644 --- a/lambda/qnabot-common-layer/package-lock.json +++ b/lambda/qnabot-common-layer/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "qnabot-common-layer", "version": "1.0.0", + "license": "Apache-2.0", "dependencies": { "lodash": "^4.17.21" }, diff --git a/lambda/qnabot-common-layer/package.json b/lambda/qnabot-common-layer/package.json index d9a54ece3..44acd9c33 100644 --- a/lambda/qnabot-common-layer/package.json +++ b/lambda/qnabot-common-layer/package.json @@ -15,7 +15,11 @@ "clean": "rm -rf node_modules", "test": "jest" }, - "author": "", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com/solutions" + }, + "license": "Apache-2.0", "dependencies": { "lodash": "^4.17.21" }, diff --git a/lambda/qnabot-common-layer/qnabot/settings.js b/lambda/qnabot-common-layer/qnabot/settings.js index de7aa4aa1..356ad00b1 100644 --- a/lambda/qnabot-common-layer/qnabot/settings.js +++ b/lambda/qnabot-common-layer/qnabot/settings.js @@ -55,26 +55,26 @@ function set_environment_variables(settings){ process.env.comprehendResult = "" if (settings.ENABLE_REDACTING) { - qnabot.log("redacting enabled"); + qnabot.debug("redacting enabled"); process.env.QNAREDACT="true"; process.env.REDACTING_REGEX=settings.REDACTING_REGEX; } else { - qnabot.log("redacting disabled"); + qnabot.debug("redacting disabled"); process.env.QNAREDACT="false"; process.env.REDACTING_REGEX=""; } if (settings.DISABLE_CLOUDWATCH_LOGGING) { - qnabot.log("disable cloudwatch logging"); + qnabot.debug("disable cloudwatch logging"); process.env.DISABLECLOUDWATCHLOGGING="true"; } else { - qnabot.log("enable cloudwatch logging"); + qnabot.debug("enable cloudwatch logging"); process.env.DISABLECLOUDWATCHLOGGING="false"; } if(settings.ENABLE_REDACTING_WITH_COMPREHEND){ - qnabot.log("enable Amazon Comprehend based redaction.") + qnabot.debug("enable Amazon Comprehend based redaction.") process.env.ENABLE_REDACTING_WITH_COMPREHEND = "true" } else { - qnabot.log("disable Amazon Comprehend based redaction.") + qnabot.debug("disable Amazon Comprehend based redaction.") process.env.ENABLE_REDACTING_WITH_COMPREHEND = "false" } if(settings.ENABLE_DEBUG_LOGGING){ diff --git a/lambda/schema/index.js b/lambda/schema/index.js index 0688080b1..7ac915799 100644 --- a/lambda/schema/index.js +++ b/lambda/schema/index.js @@ -1,16 +1,15 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -var aws=require('aws-sdk') -aws.config.region=process.env.AWS_REGION - exports.handler = (event, context, callback) => { console.log('Received event:', JSON.stringify(event, null, 2)); var schema = { quiz: require('./quiz.js'), qna: require('./qna.js'), - slottype: require('./slottype.js') + slottype: require('./slottype.js'), + text: require('./text.js') } + console.log('Returned schema:', JSON.stringify(schema, null, 2)); callback(null,schema); } diff --git a/lambda/schema/package-lock.json b/lambda/schema/package-lock.json index e5d3f64d0..4e8300e6c 100644 --- a/lambda/schema/package-lock.json +++ b/lambda/schema/package-lock.json @@ -7,10 +7,7 @@ "": { "name": "schema", "version": "1.0.0", - "license": "SEE LICENSE IN LICENSE", - "dependencies": { - "aws-sdk": "^2.1354.0" - }, + "license": "Apache-2.0", "devDependencies": { "jest": "^29.3.1" } @@ -1141,37 +1138,6 @@ "sprintf-js": "~1.0.2" } }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/aws-sdk": { - "version": "2.1354.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1354.0.tgz", - "integrity": "sha512-3aDxvyuOqMB9DqJguCq6p8momdsz0JR1axwkWOOCzHA7a35+Bw+WLmqt3pWwRjR1tGIwkkZ2CvGJObYHsOuw3w==", - "dependencies": { - "buffer": "4.9.2", - "events": "1.1.1", - "ieee754": "1.1.13", - "jmespath": "0.16.0", - "querystring": "0.2.0", - "sax": "1.2.1", - "url": "0.10.3", - "util": "^0.12.4", - "uuid": "8.0.0", - "xml2js": "0.5.0" - }, - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/babel-jest": { "version": "29.3.1", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.3.1.tgz", @@ -1269,25 +1235,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1347,34 +1294,12 @@ "node-int64": "^0.4.0" } }, - "node_modules/buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1637,14 +1562,6 @@ "node": ">=4" } }, - "node_modules/events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", - "engines": { - "node": ">=0.4.x" - } - }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -1733,14 +1650,6 @@ "node": ">=8" } }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1764,7 +1673,8 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "node_modules/gensync": { "version": "1.0.0-beta.2", @@ -1784,19 +1694,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -1847,17 +1744,6 @@ "node": ">=4" } }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -1868,6 +1754,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -1884,31 +1771,6 @@ "node": ">=8" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -1924,11 +1786,6 @@ "node": ">=10.17.0" } }, - "node_modules/ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" - }, "node_modules/import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -1970,22 +1827,8 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "node_modules/is-arrayish": { "version": "0.2.1", @@ -1993,17 +1836,6 @@ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-core-module": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", @@ -2034,20 +1866,6 @@ "node": ">=6" } }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -2069,29 +1887,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2737,14 +2532,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/jmespath": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", - "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -3155,20 +2942,6 @@ "node": ">= 6" } }, - "node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" - }, - "node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", - "engines": { - "node": ">=0.4.x" - } - }, "node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -3231,11 +3004,6 @@ "node": ">=10" } }, - "node_modules/sax": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" - }, "node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -3505,35 +3273,6 @@ "browserslist": ">= 4.21.0" } }, - "node_modules/url": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", - "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/uuid": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", - "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/v8-to-istanbul": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", @@ -3578,25 +3317,6 @@ "node": ">= 8" } }, - "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -3633,26 +3353,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/xml2js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "engines": { - "node": ">=4.0" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -4602,28 +4302,6 @@ "sprintf-js": "~1.0.2" } }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" - }, - "aws-sdk": { - "version": "2.1354.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1354.0.tgz", - "integrity": "sha512-3aDxvyuOqMB9DqJguCq6p8momdsz0JR1axwkWOOCzHA7a35+Bw+WLmqt3pWwRjR1tGIwkkZ2CvGJObYHsOuw3w==", - "requires": { - "buffer": "4.9.2", - "events": "1.1.1", - "ieee754": "1.1.13", - "jmespath": "0.16.0", - "querystring": "0.2.0", - "sax": "1.2.1", - "url": "0.10.3", - "util": "^0.12.4", - "uuid": "8.0.0", - "xml2js": "0.5.0" - } - }, "babel-jest": { "version": "29.3.1", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.3.1.tgz", @@ -4700,11 +4378,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -4745,31 +4418,12 @@ "node-int64": "^0.4.0" } }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -4955,11 +4609,6 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, - "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==" - }, "execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -5030,14 +4679,6 @@ "path-exists": "^4.0.0" } }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "requires": { - "is-callable": "^1.1.3" - } - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -5054,7 +4695,8 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "gensync": { "version": "1.0.0-beta.2", @@ -5068,16 +4710,6 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, - "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, "get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -5110,14 +4742,6 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "requires": { - "get-intrinsic": "^1.1.3" - } - }, "graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -5128,6 +4752,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -5138,19 +4763,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "requires": { - "has-symbols": "^1.0.2" - } - }, "html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -5163,11 +4775,6 @@ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" - }, "import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -5197,16 +4804,8 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "is-arrayish": { "version": "0.2.1", @@ -5214,11 +4813,6 @@ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, - "is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" - }, "is-core-module": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", @@ -5240,14 +4834,6 @@ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true }, - "is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -5260,23 +4846,6 @@ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, - "is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -5774,11 +5343,6 @@ } } }, - "jmespath": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", - "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==" - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -6082,16 +5646,6 @@ "sisteransi": "^1.0.5" } }, - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==" - }, "react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -6136,11 +5690,6 @@ "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", "dev": true }, - "sax": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -6328,32 +5877,6 @@ "picocolors": "^1.0.0" } }, - "url": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "uuid": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", - "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==" - }, "v8-to-istanbul": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", @@ -6391,19 +5914,6 @@ "isexe": "^2.0.0" } }, - "which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - } - }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -6431,20 +5941,6 @@ "signal-exit": "^3.0.7" } }, - "xml2js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - } - }, - "xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" - }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/lambda/schema/package.json b/lambda/schema/package.json index c248cfa2a..073177777 100644 --- a/lambda/schema/package.json +++ b/lambda/schema/package.json @@ -19,10 +19,7 @@ "name": "Amazon Web Services", "url": "https://aws.amazon.com/solutions" }, - "license": "SEE LICENSE IN LICENSE", - "dependencies": { - "aws-sdk": "^2.1354.0" - }, + "license": "Apache-2.0", "devDependencies": { "jest": "^29.3.1" } diff --git a/lambda/schema/test/index.test.js b/lambda/schema/test/index.test.js index 914b5627b..984dd4036 100644 --- a/lambda/schema/test/index.test.js +++ b/lambda/schema/test/index.test.js @@ -5,6 +5,7 @@ const lambda = require('../index'); const quiz = require('../quiz.js') const qna = require('../qna.js') const slottype = require('../slottype.js'); +const text = require('../text.js'); describe('when invoking lambda to obtain schema', () => { it("should return a correctly formatted object", async () => { @@ -17,6 +18,7 @@ describe('when invoking lambda to obtain schema', () => { quiz: quiz, qna: qna, slottype: slottype, + text: text, }); }); }); \ No newline at end of file diff --git a/lambda/schema/text.js b/lambda/schema/text.js new file mode 100644 index 000000000..0b1820c85 --- /dev/null +++ b/lambda/schema/text.js @@ -0,0 +1,182 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +module.exports={ + type:"object", + description:"Text passage", + properties:{ + qid:{ + type:"string", + title:"Item ID", + description:"Assign a unique identifier for this item.", + maxLength:100, + propertyOrder: 0 + }, + passage:{ + type:"string", + title:"Passage", + description:"Enter a short text passage/paragraph with information on a topic that a user may ask about.", + maxLength:8000, + propertyOrder: 3 + }, + t:{ + type:"string", + description:"Assign a topic to this item, to support follow up questions on the same topic.", + title:"Topic", + propertyOrder: 5 + }, + sa:{ + title: "Set Session Attributes", + type:"array", + items:{ + title:"Name / Value Pair", + type:"object", + properties:{ + text: { + title: "Session Attribute Name", + type : "string", + propertyOrder: 0 + }, + value: { + title: "Session Attribute Value", + maxLength:8000, + type : "string", + propertyOrder: 1 + }, + enableTranslate: { + title: "Translate Value if multi-language is enabled", + type : "boolean", + propertyOrder: 2 + } + }, + }, + propertyOrder: 7 + }, + refMarkdown:{ + type:"string", + title:"Reference Links", + description:"Attach optional markdown to your answer, e.g.: [Title](url)", + maxLength:2000, + propertyOrder: 8 + }, + r:{ + title:"Response card", + description:"Attach images and/or buttons to your answer. A reponse card must have an imageUrl or at least one button.", + type:"object", + properties:{ + title:{ + type:"string", + title:"Card Title", + description:"Required - max length of 80 after handlebars processing", + propertyOrder: 0 + }, + subTitle:{ + type:"string", + title:"Card Subtitle", + description:"Optional - max length of 80 after handlebars processing", + propertyOrder: 1 + }, + imageUrl:{ + type:"string", + description:"Optional", + title:"Card Image Url", + maxLength:2000, + propertyOrder: 2 + }, + buttons:{ + title:"Lex Buttons", + description:"Add buttons for Amazon Lex client users. NOTE: Standard Amazon Lex clients will display up to 5 buttons only (Lex limit) - this limit does not apply to Lex-Web-UI version 0.16 or later.", + type:"array", + items:{ + title:"Button", + type:"object", + properties:{ + text: { + title: "Display Text", + type : "string", + propertyOrder: 0 + }, + value: { + title: "Button Value", + type : "string", + propertyOrder: 1 + } + }, + required:["text","value"] + }, + propertyOrder: 3 + } + }, + propertyOrder:9, + required:["title"] + }, + kendraRedirectQueryText:{ + type:"string", + description:"Enter QueryText to retrieve the answer from the Kendra Fallback index specified in Settings. Answer fields above are ignored when KendraRedirect query is used.", + title:"Kendra Redirect: QueryText", + propertyOrder:10 + }, + kendraRedirectQueryConfidenceThreshold:{ + type:"string", + description:"Optional: LOW, MEDIUM, HIGH, or VERY HIGH. Defaults to the value of setting ALT_KENDRA_FALLBACK_CONFIDENCE_THRESHOLD.", + title:"Kendra Redirect Confidence score threshold.", + propertyOrder:11 + }, + kendraRedirectQueryArgs:{ + title:"Kendra query arguments", + description:"Optional key:value parameters, e.g. \"AttributeFilter\": {\"EqualsTo\": {\"Key\": \"City\", \"Value\": {\"StringValue\": \"Seattle\"}}}. Use handlebars to substitute values using session attributes or slots. See https://docs.aws.amazon.com/kendra/latest/dg/API_Query.html.", + type:"array", + items:{ + title:"Kendra query argument", + type:"string", + maxLength:2000 + }, + propertyOrder:12 + }, + l:{ + type:"string", + description:"Enter your lambda function name/ARN to dynamically create or modify answers, or to redirect to a different question.", + title:"Lambda Hook", + propertyOrder:13 + }, + args:{ + title:"Lambda Hook Arguments", + description:"If you named a lambda hook above and it requires additional information beyond what you've entered for this document, enter that information here. You should not add anything here unless the lambda hook you named has been specifically coded to handle it.", + type:"array", + items:{ + title:"Argument", + type:"string", + maxLength:2000 + }, + propertyOrder:14 + }, + conditionalChaining:{ + title:"Document Chaining: Chaining Rule", + description:"Automatically move on to another item based on the question string returned by this rule. Rule can be a single-quoted string, e.g. 'next question', or a JavaScript conditional expression that evaluates to a string, e.g. (SessionAttributes.namespace.Yes_No == \"Yes\" ) ? \"Yes question\" : \"No Question\", or a Lambda Function Name or ARN that returns a string specified as \"Lambda::FunctionName\". Function name must start with \"QNA-\".", + type:"string", + maxLength:4000, + propertyOrder:16 + }, + clientFilterValues:{ + title:"Client Filters: Values", + description:"Enter list of terms. When specified, client must provide 1 or more matching terms in request session attribute 'QNAClientFilter' for this answer to be eligible for the response. Client filters cannot be used if enableLexIntent is enabled.", + type:"string", + maxLength:100, + propertyOrder:17 + }, + tags:{ + type:"string", + description:"Specify tags for questions. Tags should be space separated. For multi-word tags please use underscore '_'.", + title:"Tags", + propertyOrder: 19 + }, + rp:{ + type:"string", + title:"Alexa Reprompt", + description:"Enter the Alexa reprompt to returned if the user does not respond. (SSML autodetection with <speak></speak>)", + maxLength:8000, + propertyOrder: 20 + }, + }, + required:["qid","passage"] +}; diff --git a/lambda/testall/package-lock.json b/lambda/testall/package-lock.json index 4e505789d..6e1fafa21 100644 --- a/lambda/testall/package-lock.json +++ b/lambda/testall/package-lock.json @@ -7,182 +7,18 @@ "": { "name": "testall", "version": "1.0.0", - "license": "ISC", + "license": "Apache-2.0", "dependencies": { - "aws-sdk": "^2.1354.0", "bluebird": "^3.5.1", "intercept-stdout": "^0.1.2", "lodash": "^4.17.21" } }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/aws-sdk": { - "version": "2.1354.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1354.0.tgz", - "integrity": "sha512-3aDxvyuOqMB9DqJguCq6p8momdsz0JR1axwkWOOCzHA7a35+Bw+WLmqt3pWwRjR1tGIwkkZ2CvGJObYHsOuw3w==", - "dependencies": { - "buffer": "4.9.2", - "events": "1.1.1", - "ieee754": "1.1.13", - "jmespath": "0.16.0", - "querystring": "0.2.0", - "sax": "1.2.1", - "url": "0.10.3", - "util": "^0.12.4", - "uuid": "8.0.0", - "xml2js": "0.5.0" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, - "node_modules/buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, "node_modules/intercept-stdout": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/intercept-stdout/-/intercept-stdout-0.1.2.tgz", @@ -191,77 +27,6 @@ "lodash.toarray": "^3.0.0" } }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "node_modules/jmespath": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", - "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -311,213 +76,14 @@ "lodash._basevalues": "^3.0.0", "lodash.keys": "^3.0.0" } - }, - "node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - }, - "node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/sax": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" - }, - "node_modules/url": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", - "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/uuid": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", - "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/xml2js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "engines": { - "node": ">=4.0" - } } }, "dependencies": { - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" - }, - "aws-sdk": { - "version": "2.1354.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1354.0.tgz", - "integrity": "sha512-3aDxvyuOqMB9DqJguCq6p8momdsz0JR1axwkWOOCzHA7a35+Bw+WLmqt3pWwRjR1tGIwkkZ2CvGJObYHsOuw3w==", - "requires": { - "buffer": "4.9.2", - "events": "1.1.1", - "ieee754": "1.1.13", - "jmespath": "0.16.0", - "querystring": "0.2.0", - "sax": "1.2.1", - "url": "0.10.3", - "util": "^0.12.4", - "uuid": "8.0.0", - "xml2js": "0.5.0" - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "requires": { - "is-callable": "^1.1.3" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, "intercept-stdout": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/intercept-stdout/-/intercept-stdout-0.1.2.tgz", @@ -526,50 +92,6 @@ "lodash.toarray": "^3.0.0" } }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" - }, - "is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "jmespath": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", - "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==" - }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -619,74 +141,6 @@ "lodash._basevalues": "^3.0.0", "lodash.keys": "^3.0.0" } - }, - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" - }, - "sax": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" - }, - "url": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "uuid": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", - "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==" - }, - "which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - } - }, - "xml2js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - } - }, - "xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" } } } diff --git a/lambda/testall/package.json b/lambda/testall/package.json index a9826202f..a156948b3 100644 --- a/lambda/testall/package.json +++ b/lambda/testall/package.json @@ -6,10 +6,12 @@ "scripts": { "test": "nodeunit test" }, - "author": "", - "license": "ISC", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com/solutions" + }, + "license": "Apache-2.0", "dependencies": { - "aws-sdk": "^2.1354.0", "bluebird": "^3.5.1", "intercept-stdout": "^0.1.2", "lodash": "^4.17.21" diff --git a/lambda/translate/package-lock.json b/lambda/translate/package-lock.json index 59dbf38bc..210728962 100644 --- a/lambda/translate/package-lock.json +++ b/lambda/translate/package-lock.json @@ -7,10 +7,7 @@ "": { "name": "translate", "version": "1.0.0", - "license": "SEE LICENSE IN LICENSE", - "dependencies": { - "aws-sdk": "^2.1354.0" - }, + "license": "Apache-2.0", "devDependencies": { "aws-sdk-mock": "^5.8.0", "jest": "^29.3.1" @@ -1172,6 +1169,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -1183,6 +1181,7 @@ "version": "2.1354.0", "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1354.0.tgz", "integrity": "sha512-3aDxvyuOqMB9DqJguCq6p8momdsz0JR1axwkWOOCzHA7a35+Bw+WLmqt3pWwRjR1tGIwkkZ2CvGJObYHsOuw3w==", + "dev": true, "dependencies": { "buffer": "4.9.2", "events": "1.1.1", @@ -1311,6 +1310,7 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, "funding": [ { "type": "github", @@ -1389,6 +1389,7 @@ "version": "4.9.2", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, "dependencies": { "base64-js": "^1.0.2", "ieee754": "^1.1.4", @@ -1405,6 +1406,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -1688,6 +1690,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", + "dev": true, "engines": { "node": ">=0.4.x" } @@ -1784,6 +1787,7 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, "dependencies": { "is-callable": "^1.1.3" } @@ -1811,7 +1815,8 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "node_modules/gensync": { "version": "1.0.0-beta.2", @@ -1835,6 +1840,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dev": true, "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -1898,6 +1904,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -1915,6 +1922,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -1935,6 +1943,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -1946,6 +1955,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -1974,7 +1984,8 @@ "node_modules/ieee754": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true }, "node_modules/import-local": { "version": "3.1.0", @@ -2017,12 +2028,14 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "node_modules/is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -2044,6 +2057,7 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -2085,6 +2099,7 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -2120,6 +2135,7 @@ "version": "1.1.10", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dev": true, "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -2137,7 +2153,8 @@ "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true }, "node_modules/isexe": { "version": "2.0.0", @@ -2788,6 +2805,7 @@ "version": "0.16.0", "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", + "dev": true, "engines": { "node": ">= 0.6.0" } @@ -3272,13 +3290,15 @@ "node_modules/punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", + "dev": true }, "node_modules/querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, "engines": { "node": ">=0.4.x" } @@ -3348,7 +3368,8 @@ "node_modules/sax": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" + "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==", + "dev": true }, "node_modules/semver": { "version": "6.3.0", @@ -3659,6 +3680,7 @@ "version": "0.10.3", "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", + "dev": true, "dependencies": { "punycode": "1.3.2", "querystring": "0.2.0" @@ -3668,6 +3690,7 @@ "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", @@ -3680,6 +3703,7 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", + "dev": true, "bin": { "uuid": "dist/bin/uuid" } @@ -3732,6 +3756,7 @@ "version": "1.1.9", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dev": true, "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -3787,6 +3812,7 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "dev": true, "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" @@ -3799,6 +3825,7 @@ "version": "11.0.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true, "engines": { "node": ">=4.0" } @@ -4783,12 +4810,14 @@ "available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true }, "aws-sdk": { "version": "2.1354.0", "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1354.0.tgz", "integrity": "sha512-3aDxvyuOqMB9DqJguCq6p8momdsz0JR1axwkWOOCzHA7a35+Bw+WLmqt3pWwRjR1tGIwkkZ2CvGJObYHsOuw3w==", + "dev": true, "requires": { "buffer": "4.9.2", "events": "1.1.1", @@ -4892,7 +4921,8 @@ "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true }, "brace-expansion": { "version": "1.1.11", @@ -4938,6 +4968,7 @@ "version": "4.9.2", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, "requires": { "base64-js": "^1.0.2", "ieee754": "^1.1.4", @@ -4954,6 +4985,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, "requires": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -5153,7 +5185,8 @@ "events": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==" + "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", + "dev": true }, "execa": { "version": "5.1.1", @@ -5229,6 +5262,7 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, "requires": { "is-callable": "^1.1.3" } @@ -5249,7 +5283,8 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "gensync": { "version": "1.0.0-beta.2", @@ -5267,6 +5302,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dev": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -5309,6 +5345,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, "requires": { "get-intrinsic": "^1.1.3" } @@ -5323,6 +5360,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -5336,12 +5374,14 @@ "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true }, "has-tostringtag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, "requires": { "has-symbols": "^1.0.2" } @@ -5361,7 +5401,8 @@ "ieee754": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true }, "import-local": { "version": "3.1.0", @@ -5392,12 +5433,14 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, "requires": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -5412,7 +5455,8 @@ "is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true }, "is-core-module": { "version": "2.11.0", @@ -5439,6 +5483,7 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -5459,6 +5504,7 @@ "version": "1.1.10", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dev": true, "requires": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -5470,7 +5516,8 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true }, "isexe": { "version": "2.0.0", @@ -5972,7 +6019,8 @@ "jmespath": { "version": "0.16.0", "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", - "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==" + "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", + "dev": true }, "js-tokens": { "version": "4.0.0", @@ -6353,12 +6401,14 @@ "punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", + "dev": true }, "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==" + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "dev": true }, "react-is": { "version": "18.2.0", @@ -6407,7 +6457,8 @@ "sax": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" + "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==", + "dev": true }, "semver": { "version": "6.3.0", @@ -6631,6 +6682,7 @@ "version": "0.10.3", "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", + "dev": true, "requires": { "punycode": "1.3.2", "querystring": "0.2.0" @@ -6640,6 +6692,7 @@ "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, "requires": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", @@ -6651,7 +6704,8 @@ "uuid": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", - "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==" + "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", + "dev": true }, "v8-to-istanbul": { "version": "9.0.1", @@ -6694,6 +6748,7 @@ "version": "1.1.9", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dev": true, "requires": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -6734,6 +6789,7 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "dev": true, "requires": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" @@ -6742,7 +6798,8 @@ "xmlbuilder": { "version": "11.0.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true }, "y18n": { "version": "5.0.8", diff --git a/lambda/translate/package.json b/lambda/translate/package.json index 5e824e66c..1bce0070c 100644 --- a/lambda/translate/package.json +++ b/lambda/translate/package.json @@ -19,10 +19,7 @@ "name": "Amazon Web Services", "url": "https://aws.amazon.com/solutions" }, - "license": "SEE LICENSE IN LICENSE", - "dependencies": { - "aws-sdk": "^2.1354.0" - }, + "license": "Apache-2.0", "devDependencies": { "aws-sdk-mock": "^5.8.0", "jest": "^29.3.1" diff --git a/package-lock.json b/package-lock.json index 30eeec281..02f4c130c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,13 @@ { "name": "qnabot-on-aws", - "version": "5.3.5", + "version": "5.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "qnabot-on-aws", - "version": "5.3.5", - "license": "SEE LICENSE IN LICENSE", + "version": "5.4.0", + "license": "Apache-2.0", "os": [ "darwin", "linux" @@ -17,7 +17,7 @@ "alexa-sdk": "^1.0.25", "async-mutex": "^0.1.3", "autosize": "^3.0.21", - "aws-lex-web-ui": "git+https://github.com/aws-samples/aws-lex-web-ui.git#semver:0.19.6", + "aws-lex-web-ui": "git+https://github.com/aws-samples/aws-lex-web-ui.git#semver:0.19.9", "aws-sdk": "^2.1354.0", "aws4": "^1.7.0", "axios": "^0.21.4", @@ -32,7 +32,6 @@ "clean-deep": "^3.0.2", "clipboard": "^1.7.1", "commander": "^8.2.0", - "crypto-js": "^3.1.9-1", "css-loader": "^3.2.0", "dir-loader": "^0.3.0", "exports-loader": "^0.6.4", @@ -257,6 +256,15 @@ "node": ">=4" } }, + "node_modules/@babel/core/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, "node_modules/@babel/core/node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -1348,6 +1356,15 @@ "semver": "^5.5.1" } }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, "node_modules/@babel/plugin-transform-shorthand-properties": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", @@ -1510,6 +1527,15 @@ "to-fast-properties": "^2.0.0" } }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, "node_modules/@babel/preset-env/node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -2633,13 +2659,13 @@ } }, "node_modules/aws-lex-web-ui": { - "version": "0.19.6", - "resolved": "git+ssh://git@github.com/aws-samples/aws-lex-web-ui.git#a51d0b50b7980481e83c06a319cb4f4e28faddf4", + "version": "0.19.9", + "resolved": "git+ssh://git@github.com/aws-samples/aws-lex-web-ui.git#16e69105f358198335293b244cb6d6feca8dcbd7", "license": "SEE LICENSE IN LICENSE", "dependencies": { "amazon-cognito-auth-js": "^1.2.4", "core-js": "^3.6.5", - "jsonwebtoken": "^8.5.1", + "jsonwebtoken": "^9.0.0", "regenerator-runtime": "^0.13.5" }, "engines": { @@ -3427,6 +3453,15 @@ "browserslist": "cli.js" } }, + "node_modules/babel-preset-env/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, "node_modules/babel-preset-es2015": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", @@ -4341,9 +4376,9 @@ } }, "node_modules/cdnjs-cdn-data/node_modules/semver": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", - "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, "bin": { "semver": "bin/semver" @@ -5152,9 +5187,9 @@ } }, "node_modules/copy-webpack-plugin/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -5186,9 +5221,9 @@ } }, "node_modules/core-js-compat/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -5324,11 +5359,6 @@ "node": ">= 8" } }, - "node_modules/crypto-js": { - "version": "3.1.9-1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz", - "integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg=" - }, "node_modules/css": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", @@ -5421,9 +5451,9 @@ } }, "node_modules/css-loader/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "bin": { "semver": "bin/semver.js" } @@ -6496,9 +6526,9 @@ } }, "node_modules/eslint/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "peer": true, "dependencies": { @@ -9021,6 +9051,15 @@ "semver": "^5.3.0" } }, + "node_modules/jsdelivr-cdn-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, "node_modules/jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -9145,35 +9184,12 @@ "node": ">= 6" } }, - "node_modules/jsdom/node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/jsdom/node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "node_modules/jsdom/node_modules/tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", - "dev": true, - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/jsdom/node_modules/xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", @@ -9278,9 +9294,9 @@ } }, "node_modules/jsonwebtoken/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -10549,9 +10565,9 @@ } }, "node_modules/normalize-package-data/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -11758,6 +11774,12 @@ "node": ">=0.4.x" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "node_modules/quick-lru": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", @@ -11956,6 +11978,14 @@ "validate-npm-package-license": "^3.0.1" } }, + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/read-pkg/node_modules/type-fest": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", @@ -12471,9 +12501,9 @@ } }, "node_modules/sass-loader/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -13404,9 +13434,9 @@ "dev": true }, "node_modules/stylus/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -13986,6 +14016,30 @@ "node": ">=6" } }, + "node_modules/tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/tr46": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", @@ -14285,9 +14339,9 @@ } }, "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "dev": true, "engines": { "node": ">= 4.0.0" @@ -14407,6 +14461,16 @@ "querystring": "0.2.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/urlcode-json": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/urlcode-json/-/urlcode-json-0.0.5.tgz", @@ -15698,9 +15762,9 @@ } }, "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -16019,7 +16083,7 @@ "json5": "^2.1.0", "lodash": "^4.17.13", "resolve": "^1.3.2", - "semver": "^5.4.1", + "semver": "^5.7.2", "source-map": "^0.5.0" }, "dependencies": { @@ -16101,6 +16165,12 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -17109,7 +17179,15 @@ "@babel/helper-module-imports": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", "resolve": "^1.8.1", - "semver": "^5.5.1" + "semver": "^5.7.2" + }, + "dependencies": { + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + } } }, "@babel/plugin-transform-shorthand-properties": { @@ -17256,7 +17334,7 @@ "core-js-compat": "^3.1.1", "invariant": "^2.2.2", "js-levenshtein": "^1.1.3", - "semver": "^5.5.0" + "semver": "^5.7.2" }, "dependencies": { "@babel/types": { @@ -17270,6 +17348,12 @@ "to-fast-properties": "^2.0.0" } }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -17353,7 +17437,7 @@ "ignore": "^4.0.6", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "3.0.5", + "minimatch": "^3.0.5", "strip-json-comments": "^3.1.1" }, "dependencies": { @@ -17392,7 +17476,7 @@ "requires": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", - "minimatch": "3.0.5" + "minimatch": "^3.0.5" } }, "@humanwhocodes/object-schema": { @@ -18248,8 +18332,8 @@ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" }, "aws-lex-web-ui": { - "version": "git+ssh://git@github.com/aws-samples/aws-lex-web-ui.git#a51d0b50b7980481e83c06a319cb4f4e28faddf4", - "from": "aws-lex-web-ui@git+https://github.com/aws-samples/aws-lex-web-ui.git#semver:0.19.6", + "version": "git+ssh://git@github.com/aws-samples/aws-lex-web-ui.git#16e69105f358198335293b244cb6d6feca8dcbd7", + "from": "aws-lex-web-ui@git+https://github.com/aws-samples/aws-lex-web-ui.git#semver:0.19.9", "requires": { "amazon-cognito-auth-js": "^1.2.4", "core-js": "^3.6.5", @@ -18390,7 +18474,7 @@ "debug": "^2.6.9", "json5": "^1.0.2", "lodash": "^4.17.4", - "minimatch": "3.0.5", + "minimatch": "^3.0.5", "path-is-absolute": "^1.0.1", "private": "^0.1.8", "slash": "^1.0.0", @@ -18996,7 +19080,7 @@ "babel-plugin-transform-regenerator": "^6.22.0", "browserslist": "^3.2.6", "invariant": "^2.2.2", - "semver": "^5.3.0" + "semver": "^5.7.2" }, "dependencies": { "browserslist": { @@ -19008,6 +19092,12 @@ "caniuse-lite": "^1.0.30000844", "electron-to-chromium": "^1.3.47" } + }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true } } }, @@ -19795,7 +19885,7 @@ "google-cdn-data": "^0.1.6", "jsdelivr-cdn-data": "git://github.com/shahata/jsdelivr-cdn-data.git#d014a2ad1bdfb4c6e3d3cefc7f264435281b91e0", "lodash": "^4.17.11", - "minimatch": "3.0.5" + "minimatch": "^3.0.5" } }, "cdnjs-cdn-data": { @@ -19804,13 +19894,13 @@ "integrity": "sha1-hl00uk5I3Rtz/WaOJKYaWt+biyE=", "dev": true, "requires": { - "semver": "~5.0.1" + "semver": "^5.7.2" }, "dependencies": { "semver": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", - "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true } } @@ -20381,7 +20471,7 @@ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "requires": { - "semver": "^6.0.0" + "semver": "^6.3.1" } }, "normalize-path": { @@ -20441,9 +20531,9 @@ } }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true }, "webpack-sources": { @@ -20470,13 +20560,13 @@ "dev": true, "requires": { "browserslist": "^4.6.6", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -20594,11 +20684,6 @@ } } }, - "crypto-js": { - "version": "3.1.9-1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz", - "integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg=" - }, "css": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", @@ -20628,7 +20713,7 @@ "postcss-modules-values": "^3.0.0", "postcss-value-parser": "^4.1.0", "schema-utils": "^2.7.0", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "dependencies": { "json5": { @@ -20665,9 +20750,9 @@ } }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" } } }, @@ -21318,12 +21403,12 @@ "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "3.0.5", + "minimatch": "^3.0.5", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "progress": "^2.0.0", "regexpp": "^3.2.0", - "semver": "^7.2.1", + "semver": "^7.5.2", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0", @@ -21429,7 +21514,7 @@ "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "word-wrap": "^1.2.4" } }, "prelude-ls": { @@ -21447,9 +21532,9 @@ "peer": true }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "peer": true, "requires": { @@ -22336,7 +22421,7 @@ "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "3.0.5", + "minimatch": "^3.0.5", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } @@ -23433,7 +23518,15 @@ "dev": true, "from": "jsdelivr-cdn-data@git://github.com/shahata/jsdelivr-cdn-data.git#d014a2ad1bdfb4c6e3d3cefc7f264435281b91e0", "requires": { - "semver": "^5.3.0" + "semver": "^5.7.2" + }, + "dependencies": { + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + } } }, "jsdom": { @@ -23460,7 +23553,7 @@ "parse5": "6.0.1", "saxes": "^5.0.1", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", + "tough-cookie": "^4.1.3", "w3c-hr-time": "^1.0.2", "w3c-xmlserializer": "^2.0.0", "webidl-conversions": "^6.1.0", @@ -23529,29 +23622,12 @@ "mime-types": "^2.1.12" } }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", - "dev": true, - "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - } - }, "xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", @@ -23633,7 +23709,7 @@ "jws": "^3.2.2", "lodash": "^4.17.21", "ms": "^2.1.1", - "semver": "^7.3.8" + "semver": "^7.5.2" }, "dependencies": { "lru-cache": { @@ -23645,9 +23721,9 @@ } }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "requires": { "lru-cache": "^6.0.0" } @@ -24644,7 +24720,7 @@ "requires": { "hosted-git-info": "^4.0.1", "is-core-module": "^2.5.0", - "semver": "^7.3.4", + "semver": "^7.5.2", "validate-npm-package-license": "^3.0.1" }, "dependencies": { @@ -24657,9 +24733,9 @@ } }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "requires": { "lru-cache": "^6.0.0" } @@ -24855,7 +24931,7 @@ "levn": "~0.3.0", "prelude-ls": "~1.1.2", "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "word-wrap": "^1.2.4" } }, "ora": { @@ -25654,6 +25730,12 @@ "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "quick-lru": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", @@ -25747,10 +25829,15 @@ "requires": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", + "semver": "^5.7.2", "validate-npm-package-license": "^3.0.1" } }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==" + }, "type-fest": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", @@ -25845,7 +25932,7 @@ "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", "requires": { - "minimatch": "3.0.5" + "minimatch": "^3.0.5" } }, "redent": { @@ -26189,7 +26276,7 @@ "loader-utils": "^1.4.2", "neo-async": "^2.5.0", "pify": "^4.0.1", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "dependencies": { "json5": { @@ -26219,9 +26306,9 @@ "dev": true }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -26937,7 +27024,7 @@ "mkdirp": "~0.5.x", "safer-buffer": "^2.1.2", "sax": "~1.2.4", - "semver": "^6.0.0", + "semver": "^6.3.1", "source-map": "^0.7.3" }, "dependencies": { @@ -26963,9 +27050,9 @@ "dev": true }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true }, "source-map": { @@ -27481,6 +27568,26 @@ "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", "dev": true }, + "tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "dev": true, + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "dependencies": { + "punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true + } + } + }, "tr46": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", @@ -27696,9 +27803,9 @@ } }, "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "dev": true }, "unpipe": { @@ -27801,6 +27908,16 @@ "querystring": "0.2.0" } }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "urlcode-json": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/urlcode-json/-/urlcode-json-0.0.5.tgz", @@ -28816,9 +28933,9 @@ } }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true }, "worker-farm": { diff --git a/package.json b/package.json index a7ee500a3..1bf204a76 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,14 @@ { "name": "qnabot-on-aws", - "version": "5.3.5", + "version": "5.4.0", "engines": { "node": ">=12.16.1", "npm": ">=7.8.0" }, + "config": { + "lambdaRuntime": "nodejs18.x", + "pythonRuntime": "python3.10" + }, "engineStrict": true, "os": [ "darwin", @@ -38,8 +42,11 @@ "type": "git", "url": "https://github.com/aws-solutions/qnabot-on-aws.git" }, - "author": "AWS", - "license": "SEE LICENSE IN LICENSE", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com/solutions" + }, + "license": "Apache-2.0", "bugs": { "url": "https://github.com/aws-solutions/qnabot-on-aws/issues" }, @@ -49,7 +56,7 @@ "alexa-sdk": "^1.0.25", "async-mutex": "^0.1.3", "autosize": "^3.0.21", - "aws-lex-web-ui": "git+https://github.com/aws-samples/aws-lex-web-ui.git#semver:0.19.6", + "aws-lex-web-ui": "git+https://github.com/aws-samples/aws-lex-web-ui.git#semver:0.19.9", "aws-sdk": "^2.1354.0", "aws4": "^1.7.0", "axios": "^0.21.4", @@ -64,7 +71,6 @@ "clean-deep": "^3.0.2", "clipboard": "^1.7.1", "commander": "^8.2.0", - "crypto-js": "^3.1.9-1", "css-loader": "^3.2.0", "dir-loader": "^0.3.0", "exports-loader": "^0.6.4", @@ -168,11 +174,13 @@ "chokidar@2.1.8": { "glob-parent": "^5.1.2" }, - "minimatch": "3.0.5", + "minimatch": "^3.0.5", "loader-utils@<1.4.2": "^1.4.2", "json5@<1.0.2": "^1.0.2", - "aws-lex-web-ui": { - "jsonwebtoken@<9.0.0": "$jsonwebtoken" - } + "word-wrap@<1.2.4": "^1.2.4", + "tough-cookie@<4.1.3": "^4.1.3", + "semver@<5.7.2": "^5.7.2", + "semver@6.3.0": "^6.3.1", + "semver@7.0.0 - 7.5.2": "^7.5.2" } } diff --git a/source/requirements-dev.txt b/source/requirements-dev.txt index 0e82301e6..9eddaf138 100644 --- a/source/requirements-dev.txt +++ b/source/requirements-dev.txt @@ -1,5 +1,5 @@ autopep8==2.0.0 black==23.3.0 flake8==6.0.0 -mypy==1.3.0 +mypy==1.4.0 pylint==2.17.0 \ No newline at end of file diff --git a/source/tests/aws_solutions/qnabot/fixtures/qnabot-test-template.yaml b/source/tests/aws_solutions/qnabot/fixtures/qnabot-test-template.yaml index c955defde..e0fd526b7 100644 --- a/source/tests/aws_solutions/qnabot/fixtures/qnabot-test-template.yaml +++ b/source/tests/aws_solutions/qnabot/fixtures/qnabot-test-template.yaml @@ -9,9 +9,21 @@ Resources: ImportBucket: Type: AWS::S3::Bucket BucketName: test_import_bucket + BucketEncryption: + ServerSideEncryptionConfiguration: + ServerSideEncryptionByDefault: + SSEAlgorithm: AES256 + VersioningConfiguration: + Status: Enabled ExportBucket: Type: AWS::S3::Bucket BucketName: test_export_bucket + BucketEncryption: + ServerSideEncryptionConfiguration: + ServerSideEncryptionByDefault: + SSEAlgorithm: AES256 + VersioningConfiguration: + Status: Enabled ESProxyLambdaRole: Type: AWS::IAM::Role Properties: diff --git a/templates/dev/lambda.js b/templates/dev/lambda.js index 518567620..3efdc7eb6 100644 --- a/templates/dev/lambda.js +++ b/templates/dev/lambda.js @@ -25,7 +25,7 @@ module.exports={ "Handler": "index.handler", "MemorySize": "128", "Role": {"Fn::GetAtt": ["LambdaRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300 } }, diff --git a/templates/dev/master.js b/templates/dev/master.js index 6fb0595e0..7631aa381 100644 --- a/templates/dev/master.js +++ b/templates/dev/master.js @@ -1,6 +1,5 @@ -var stack=require('../util').stacktest var Promise=require('bluebird') -var config=require('../../config') +var config=require('../../config.json') var outputs=require('../../bin/exports') module.exports=Promise.join( @@ -16,6 +15,9 @@ module.exports=Promise.join( base.Parameters.LexBotVersion.Default = config.LexBotVersion ? config.LexBotVersion : base.Parameters.LexBotVersion.Default base.Parameters.FulfillmentConcurrency.Default = config.FulfillmentConcurrency ? config.FulfillmentConcurrency : base.Parameters.FulfillmentConcurrency.Default base.Parameters.LexV2BotLocaleIds.Default = config.LexV2BotLocaleIds ? config.LexV2BotLocaleIds : base.Parameters.LexV2BotLocaleIds.Default + base.Parameters.EmbeddingsApi.Default = config.EmbeddingsApi ? config.EmbeddingsApi : base.Parameters.EmbeddingsApi.Default + base.Parameters.LLMApi.Default = config.LLMApi ? config.LLMApi : base.Parameters.LLMApi.Default + base.Parameters.InstallLexResponseBots.Default = config.InstallLexResponseBots ? config.InstallLexResponseBots : base.Parameters.InstallLexResponseBots.Default return base }) diff --git a/templates/examples/examples/examples/TextPassage-NurseryRhymeExamples.json b/templates/examples/examples/examples/TextPassage-NurseryRhymeExamples.json new file mode 100644 index 000000000..656dee2c8 --- /dev/null +++ b/templates/examples/examples/examples/TextPassage-NurseryRhymeExamples.json @@ -0,0 +1,19 @@ +{ + "qna": [ + { + "passage": "Humpty Dumpty sat on the wall,\nHumpty Dumpty had a great fall,\nAll the king's horses and all the king's men,\nCouldn't put Humpty together again.", + "type": "text", + "qid": "0.HumptyDumpty" + }, + { + "r": { + "imageUrl": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9d/464249_Little-Bo-Peep.jpg/220px-464249_Little-Bo-Peep.jpg", + "title": "Bo Peep" + }, + "passage": "Little Bo-Peep has lost her sheep,\nand doesn't know where to find them;\nleave them alone, And they'll come home,\nwagging (bringing) their tails behind them.", + "refMarkdown": "Source Link: [Little Bo Beep](https://en.wikipedia.org/wiki/Little_Bo-Peep)", + "type": "text", + "qid": "0.BoPeep" + } + ] +} \ No newline at end of file diff --git a/templates/examples/examples/examples/TextPassage-NurseryRhymeExamples.txt b/templates/examples/examples/examples/TextPassage-NurseryRhymeExamples.txt new file mode 100644 index 000000000..59e80d9b4 --- /dev/null +++ b/templates/examples/examples/examples/TextPassage-NurseryRhymeExamples.txt @@ -0,0 +1 @@ +Imports sample text passage items for testing passage embeddings and LLM QA Summarization. \ No newline at end of file diff --git a/templates/examples/examples/index.js b/templates/examples/examples/index.js index 7f4e1810e..a638a526b 100644 --- a/templates/examples/examples/index.js +++ b/templates/examples/examples/index.js @@ -150,21 +150,24 @@ module.exports=Object.assign( "Handler": "cfn.handler", "MemorySize": "128", "Role":{"Ref":"CFNLambdaRole"} , - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { "SubnetIds": { "Fn::Split" : [ ",", {"Ref": "VPCSubnetIdList"} ] }, "SecurityGroupIds": { "Fn::Split" : [ ",", {"Ref": "VPCSecurityGroupIdList"} ] }, }, {"Ref" : "AWS::NoValue"} ] - }, - "TracingConfig" : { - "Fn::If": [ "XRAYEnabled", {"Mode": "Active"}, - {"Ref" : "AWS::NoValue"} ] - }, + }, + "TracingConfig" : { + "Fn::If": [ "XRAYEnabled", {"Mode": "Active"}, + {"Ref" : "AWS::NoValue"} ] + }, + "Layers":[ + {"Ref":"AwsSdkLayerLambdaLayer"} + ], "Tags":[{ - Key:"Type", - Value:"CustomResource" + Key:"Type", + Value:"CustomResource" }] }, "Metadata": util.cfnNag(["W92", "W58"]) @@ -332,7 +335,7 @@ function jslambda(name){ "Handler":`js/${name}.handler`, "MemorySize": "128", "Role": {"Fn::GetAtt": ["ExampleLambdaRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -344,6 +347,9 @@ function jslambda(name){ "Fn::If": [ "XRAYEnabled", {"Mode": "Active"}, {"Ref" : "AWS::NoValue"} ] }, + "Layers":[ + {"Ref":"AwsSdkLayerLambdaLayer"} + ], "Tags":[{ Key:"Type", Value:"Example" @@ -377,7 +383,7 @@ function pylambda(name){ "Handler":`py/${name}.handler`, "MemorySize": "128", "Role": {"Fn::GetAtt": ["ExampleLambdaRole","Arn"]}, - "Runtime": "python3.9", + "Runtime": process.env.npm_package_config_pythonRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { diff --git a/templates/examples/examples/package-lock.json b/templates/examples/examples/package-lock.json index 3de1c80ee..8f42cf370 100644 --- a/templates/examples/examples/package-lock.json +++ b/templates/examples/examples/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "examples", "version": "1.0.0", - "license": "ISC", + "license": "Apache-2.0", "dependencies": { "bluebird": "^3.5.1", "cfn-response": "^1.0.1", diff --git a/templates/examples/examples/package.json b/templates/examples/examples/package.json index d1023cc1d..0ec08e30d 100644 --- a/templates/examples/examples/package.json +++ b/templates/examples/examples/package.json @@ -6,8 +6,11 @@ "scripts": { "test": "nodeunit test.js" }, - "author": "", - "license": "ISC", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com/solutions" + }, + "license": "Apache-2.0", "dependencies": { "bluebird": "^3.5.1", "cfn-response": "^1.0.1", diff --git a/templates/examples/examples/responsebots-lexv2.js b/templates/examples/examples/responsebots-lexv2.js index fa48da9e4..5c0ce63d2 100644 --- a/templates/examples/examples/responsebots-lexv2.js +++ b/templates/examples/examples/responsebots-lexv2.js @@ -2519,5 +2519,5 @@ exports.names = [ exports.outputs = _.fromPairs(exports.names.map(x => { - return [x, {Value: {"Fn::If": ["CreateLexResponseBots", {"Fn::Join": ["", ["LexV2::", {"Ref": "ResponseBot" + x + "V2"}, "/", {"Fn::GetAtt": ["ResponseBot" + x + "AliasV2", "BotAliasId"]}, "/", "en_US"]]}, "ReponseBots disabled during stack create/update"]}}]; + return [x, {Value: {"Fn::If": ["CreateLexResponseBots", {"Fn::Join": ["", ["LexV2::", {"Ref": "ResponseBot" + x + "V2"}, "/", {"Fn::GetAtt": ["ResponseBot" + x + "AliasV2", "BotAliasId"]}, "/", "en_US"]]}, "ReponseBots disabled"]}}]; })); diff --git a/templates/examples/examples/responsebots.js b/templates/examples/examples/responsebots.js index 8cec87836..daec5f1e5 100644 --- a/templates/examples/examples/responsebots.js +++ b/templates/examples/examples/responsebots.js @@ -2091,6 +2091,6 @@ exports.names=[ exports.outputs=_.fromPairs(exports.names.map(x=>{ - return [x,{Value:{"Fn::If": ["CreateLexV1ResponseBots", {"Ref":x}, "Lex V1 ReponseBots disabled during stack create/update"]}}]; + return [x,{Value:{"Fn::If": ["CreateLexV1ResponseBots", {"Ref":x}, "LexV2 only"]}}]; })); diff --git a/templates/examples/extensions/index.js b/templates/examples/extensions/index.js index 941cd4318..68edfda39 100644 --- a/templates/examples/extensions/index.js +++ b/templates/examples/extensions/index.js @@ -58,7 +58,7 @@ module.exports=Object.assign( "Handler": "ui_import.handler", "MemorySize": "128", "Role":{"Ref":"CFNLambdaRole"} , - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -70,6 +70,9 @@ module.exports=Object.assign( "Fn::If": [ "XRAYEnabled", {"Mode": "Active"}, {"Ref" : "AWS::NoValue"} ] }, + "Layers":[ + {"Ref":"AwsSdkLayerLambdaLayer"} + ], "Tags":[{ Key:"Type", Value:"CustomResource" @@ -117,7 +120,7 @@ module.exports=Object.assign( ], ], }, - CompatibleRuntimes: ["nodejs16.x"], + CompatibleRuntimes: [process.env.npm_package_config_lambdaRuntime], }, }, "ExtensionsInvokePolicy": { @@ -211,8 +214,8 @@ module.exports=Object.assign( } ] } - }, - { + }, + { "PolicyName" : "QNASecretsManagerLambda", "PolicyDocument" : { "Version": "2012-10-17", @@ -223,7 +226,7 @@ module.exports=Object.assign( "secretsmanager:GetResourcePolicy", "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret" - ], + ], "Resource": [ {"Fn::Join": ["",["arn:aws:secretsmanager:",{ "Ref" : "AWS::Region" },":",{ "Ref" : "AWS::AccountId" },":secret:qna-*"]]}, {"Fn::Join": ["",["arn:aws:secretsmanager:",{ "Ref" : "AWS::Region" },":",{ "Ref" : "AWS::AccountId" },":secret:QNA-*"]]} @@ -259,7 +262,7 @@ function jslambda(name){ "Handler":`${name}.handler`, "MemorySize": "2048", "Role": {"Fn::GetAtt": ["ExtensionLambdaRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -267,12 +270,15 @@ function jslambda(name){ "SecurityGroupIds": { "Fn::Split" : [ ",", {"Ref": "VPCSecurityGroupIdList"} ] }, }, {"Ref" : "AWS::NoValue"} ] }, - "Layers":[{"Ref":"JsLambdaHookSDKLambdaLayer"}], + "Layers":[ + {"Ref":"AwsSdkLayerLambdaLayer"}, + {"Ref":"JsLambdaHookSDKLambdaLayer"} + ], "TracingConfig" : { "Fn::If": [ "XRAYEnabled", {"Mode": "Active"}, {"Ref" : "AWS::NoValue"} ] }, - "Tags":[{ + "Tags":[{ Key:"Type", Value:"LambdaHook" }] @@ -304,18 +310,18 @@ function pylambda(name){ "Handler":`${name}.handler`, "MemorySize": "2048", "Role": {"Fn::GetAtt": ["ExtensionLambdaRole","Arn"]}, - "Runtime": "python3.9", + "Runtime": process.env.npm_package_config_pythonRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { "SubnetIds": { "Fn::Split" : [ ",", {"Ref": "VPCSubnetIdList"} ] }, "SecurityGroupIds": { "Fn::Split" : [ ",", {"Ref": "VPCSecurityGroupIdList"} ] }, }, {"Ref" : "AWS::NoValue"} ] - }, - "TracingConfig" : { - "Fn::If": [ "XRAYEnabled", {"Mode": "Active"}, - {"Ref" : "AWS::NoValue"} ] - }, + }, + "TracingConfig" : { + "Fn::If": [ "XRAYEnabled", {"Mode": "Active"}, + {"Ref" : "AWS::NoValue"} ] + }, "Tags":[{ Key:"Type", Value:"LambdaHook" diff --git a/templates/examples/extensions/js_lambda_hooks/CreateRecentTopicsResponse/package-lock.json b/templates/examples/extensions/js_lambda_hooks/CreateRecentTopicsResponse/package-lock.json index 236677349..3978b2e80 100644 --- a/templates/examples/extensions/js_lambda_hooks/CreateRecentTopicsResponse/package-lock.json +++ b/templates/examples/extensions/js_lambda_hooks/CreateRecentTopicsResponse/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "createrecenttopicsresponse", "version": "1.0.0", - "license": "ISC", + "license": "Apache-2.0", "dependencies": { "lodash": "^4.17.21" } diff --git a/templates/examples/extensions/js_lambda_hooks/CreateRecentTopicsResponse/package.json b/templates/examples/extensions/js_lambda_hooks/CreateRecentTopicsResponse/package.json index dedd75d51..b189c9d0a 100644 --- a/templates/examples/extensions/js_lambda_hooks/CreateRecentTopicsResponse/package.json +++ b/templates/examples/extensions/js_lambda_hooks/CreateRecentTopicsResponse/package.json @@ -6,8 +6,11 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, - "author": "", - "license": "ISC", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com/solutions" + }, + "license": "Apache-2.0", "dependencies": { "lodash": "^4.17.21" } diff --git a/templates/examples/extensions/js_lambda_hooks/CustomJSHook/package-lock.json b/templates/examples/extensions/js_lambda_hooks/CustomJSHook/package-lock.json index 8c1afc9e6..44777cfce 100644 --- a/templates/examples/extensions/js_lambda_hooks/CustomJSHook/package-lock.json +++ b/templates/examples/extensions/js_lambda_hooks/CustomJSHook/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "examples", "version": "1.0.0", - "license": "ISC", + "license": "Apache-2.0", "dependencies": { "bluebird": "^3.5.1", "cfn-response": "^1.0.1", diff --git a/templates/examples/extensions/js_lambda_hooks/CustomJSHook/package.json b/templates/examples/extensions/js_lambda_hooks/CustomJSHook/package.json index d1023cc1d..0ec08e30d 100644 --- a/templates/examples/extensions/js_lambda_hooks/CustomJSHook/package.json +++ b/templates/examples/extensions/js_lambda_hooks/CustomJSHook/package.json @@ -6,8 +6,11 @@ "scripts": { "test": "nodeunit test.js" }, - "author": "", - "license": "ISC", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com/solutions" + }, + "license": "Apache-2.0", "dependencies": { "bluebird": "^3.5.1", "cfn-response": "^1.0.1", diff --git a/templates/examples/extensions/py_lambda_hooks/CanvasLMSHook/requirements.txt b/templates/examples/extensions/py_lambda_hooks/CanvasLMSHook/requirements.txt index f536ff7df..386dffab1 100644 --- a/templates/examples/extensions/py_lambda_hooks/CanvasLMSHook/requirements.txt +++ b/templates/examples/extensions/py_lambda_hooks/CanvasLMSHook/requirements.txt @@ -1,7 +1,5 @@ -python-dateutil==2.8.1 urllib3==1.26.5 canvasapi==3.2.0 idna==2.10 -pytz==2021.1 requests==2.31.0 beautifulsoup4==4.12.0 diff --git a/templates/examples/extensions/ui_imports/package-lock.json b/templates/examples/extensions/ui_imports/package-lock.json index cee7461e6..33223905a 100644 --- a/templates/examples/extensions/ui_imports/package-lock.json +++ b/templates/examples/extensions/ui_imports/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "ui_import", "version": "1.0.0", - "license": "ISC", + "license": "Apache-2.0", "dependencies": { "bluebird": "^3.5.1", "cfn-response": "^1.0.1", diff --git a/templates/examples/extensions/ui_imports/package.json b/templates/examples/extensions/ui_imports/package.json index 14674bc74..0cfc87f0f 100644 --- a/templates/examples/extensions/ui_imports/package.json +++ b/templates/examples/extensions/ui_imports/package.json @@ -6,8 +6,11 @@ "scripts": { "test": "nodeunit test.js" }, - "author": "", - "license": "ISC", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com/solutions" + }, + "license": "Apache-2.0", "dependencies": { "bluebird": "^3.5.1", "cfn-response": "^1.0.1", diff --git a/templates/examples/index.js b/templates/examples/index.js index 3167aa7eb..c6f6649a8 100644 --- a/templates/examples/index.js +++ b/templates/examples/index.js @@ -12,7 +12,7 @@ const outputs=Object.assign(outputs1,outputs2,outputSNSTopic); module.exports={ "Resources":resources, "AWSTemplateFormatVersion": "2010-09-09", - "Description": "(SO0189n-example) QnABot nested example resources", + "Description": `(SO0189n-example) QnABot nested example resources - Version v${process.env.npm_package_version}`, "Mappings": {}, "Outputs": outputs, "Parameters": { @@ -26,7 +26,7 @@ module.exports={ "FeedbackFirehose":{"Type":"String"}, "FeedbackFirehoseName":{"Type":"String"}, "CFNLambda":{"Type":"String"}, - "CFNLambdaRole": {"Type":"String"}, + "CFNLambdaRole":{"Type":"String"}, "ApiUrlName":{"Type":"String"}, "AssetBucket":{"Type":"String"}, "QIDLambdaArn":{"Type":"String"}, @@ -36,6 +36,7 @@ module.exports={ "XraySetting": {"Type": "String"}, "DefaultQnABotSettings": {"Type":"String"}, "InstallLexResponseBots": {"Type":"String"}, + "AwsSdkLayerLambdaLayer":{"Type":"String"}, }, "Conditions": { "VPCEnabled": { "Fn::Not": [ diff --git a/templates/export/index.js b/templates/export/index.js index ed4bcd219..7673dd8d0 100644 --- a/templates/export/index.js +++ b/templates/export/index.js @@ -9,7 +9,7 @@ module.exports={ "Resources":_.assign.apply({},files), "Conditions": {}, "AWSTemplateFormatVersion": "2010-09-09", - "Description": "(SO0189n-export) QnABot nested export resources", + "Description": `(SO0189n-export) QnABot nested export resources - Version v${process.env.npm_package_version}`, "Outputs": require('./outputs'), "Parameters": { "CFNLambda":{"Type":"String"}, diff --git a/templates/export/resources.js b/templates/export/resources.js index 10af2ef50..8393771d5 100644 --- a/templates/export/resources.js +++ b/templates/export/resources.js @@ -57,7 +57,7 @@ module.exports = Object.assign( "Handler": "index.handler", "MemorySize": "1024", "Role": {"Fn::GetAtt": ["ExportRole", "Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig": { "Fn::If": ["VPCEnabled", { @@ -68,6 +68,9 @@ module.exports = Object.assign( "TracingConfig": { "Fn::If": ["XRAYEnabled", {"Mode": "Active"}, {"Ref": "AWS::NoValue"}] }, + "Layers":[ + {"Ref":"AwsSdkLayerLambdaLayer"} + ], "Tags": [{ Key: "Type", Value: "Export" @@ -130,7 +133,7 @@ module.exports = Object.assign( "Handler": "index.handler", "MemorySize": "1024", "Role": {"Fn::GetAtt": ["ExportRole", "Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig": { "Fn::If": ["VPCEnabled", { @@ -141,6 +144,9 @@ module.exports = Object.assign( "TracingConfig": { "Fn::If": ["XRAYEnabled", {"Mode": "Active"}, {"Ref": "AWS::NoValue"}] }, + "Layers":[ + {"Ref":"AwsSdkLayerLambdaLayer"} + ], "Tags": [{ Key: "Type", Value: "Export" @@ -288,7 +294,7 @@ module.exports = Object.assign( "Handler": "index.step", "MemorySize": "1024", "Role": {"Fn::GetAtt": ["ExportRole", "Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig": { "Fn::If": ["VPCEnabled", { @@ -300,6 +306,9 @@ module.exports = Object.assign( "Fn::If": ["XRAYEnabled", {"Mode": "Active"}, {"Ref": "AWS::NoValue"}] }, + "Layers":[ + {"Ref":"AwsSdkLayerLambdaLayer"} + ], "Tags": [{ Key: "Type", Value: "Export" @@ -390,7 +399,7 @@ module.exports = Object.assign( "Handler": "kendraSync.performSync", "MemorySize": "1024", "Role": {"Fn::GetAtt": ["KendraSyncRole", "Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig": { "Fn::If": ["VPCEnabled", { @@ -597,7 +606,7 @@ module.exports = Object.assign( Handler: "index.handler", MemorySize: "1024", Role: {"Fn::GetAtt": ["TranslateRole", "Arn"]}, - Runtime: "nodejs16.x", + Runtime: process.env.npm_package_config_lambdaRuntime, Timeout: 300, "VpcConfig": { "Fn::If": ["VPCEnabled", { @@ -608,6 +617,9 @@ module.exports = Object.assign( "TracingConfig": { "Fn::If": ["XRAYEnabled", {"Mode": "Active"}, {"Ref": "AWS::NoValue"}] }, + "Layers":[ + {"Ref":"AwsSdkLayerLambdaLayer"} + ], Tags: [ { Key: "Type", @@ -960,7 +972,7 @@ module.exports = Object.assign( Handler: "kendra_webcrawler.handler", MemorySize: "2048", Role: {"Fn::GetAtt": ["KendraNativeCrawlerRole", "Arn"]}, - Runtime: "python3.9", + Runtime: process.env.npm_package_config_pythonRuntime, Timeout: 900, Tags: [ { @@ -1029,7 +1041,7 @@ module.exports = Object.assign( Handler: "kendra_webcrawler_schedule_updater.handler", MemorySize: "2048", Role: {"Fn::GetAtt": ["KendraNativeCrawlerRole", "Arn"]}, - Runtime: "python3.9", + Runtime: process.env.npm_package_config_pythonRuntime, Timeout: 900, Tags: [ { @@ -1094,7 +1106,7 @@ module.exports = Object.assign( Handler: "kendra_webcrawler_status.handler", MemorySize: "2048", Role: {"Fn::GetAtt": ["KendraNativeCrawlerRole", "Arn"]}, - Runtime: "python3.9", + Runtime: process.env.npm_package_config_pythonRuntime, Timeout: 900, Tags: [ { diff --git a/templates/import/index.js b/templates/import/index.js index 88eb93694..f199646ff 100644 --- a/templates/import/index.js +++ b/templates/import/index.js @@ -9,7 +9,7 @@ module.exports={ "Resources":_.assign.apply({},files), "Conditions": {}, "AWSTemplateFormatVersion": "2010-09-09", - "Description": "(SO0189n-import) QnABot nested import resources", + "Description": `(SO0189n-import) QnABot nested import resources - Version v${process.env.npm_package_version}`, "Outputs": require('./outputs'), "Parameters": { "CFNLambda":{"Type":"String"}, diff --git a/templates/import/resources.js b/templates/import/resources.js index 76830aa7c..e47e21ca3 100644 --- a/templates/import/resources.js +++ b/templates/import/resources.js @@ -36,7 +36,7 @@ module.exports=Object.assign( "Handler": "index.start", "MemorySize": "1024", "Role": {"Fn::GetAtt": ["ImportRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -86,7 +86,7 @@ module.exports=Object.assign( "Handler": "index.step", "MemorySize": "1024", "Role": {"Fn::GetAtt": ["ImportRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 900, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -149,14 +149,14 @@ module.exports=Object.assign( ] } }, - { + { "Fn::If": [ "EmbeddingsSagemaker", { "PolicyName" : "SagemakerEmbeddingsPolicy", "PolicyDocument" : { "Version": "2012-10-17", - "Statement": [ + "Statement": [ { "Effect": "Allow", "Action": [ diff --git a/templates/master/appregistry.js b/templates/master/appregistry.js new file mode 100644 index 000000000..0b7e107ca --- /dev/null +++ b/templates/master/appregistry.js @@ -0,0 +1,111 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +module.exports={ + "Application": { + "Type": "AWS::ServiceCatalogAppRegistry::Application", + "Properties": { + "Description": "Service Catalog application to track and manage all your resources for the solution qnabot-on-aws", + "Name": { //This property has a 256 character limit + "Fn::Join": [ + "-", + [ + //application names can not start with 'AWS', so prepend 'App' to all Applications + //this defends against errors thrown when stack names start with 'AWS' + "App", + { "Ref": "AWS::StackName" }, + { "Fn::FindInMap": ["Solution", "Data", "AppRegistryApplicationName"] } + ] + ] + }, + "Tags": { + "Solutions:SolutionID": { "Fn::FindInMap": ["Solution", "Data", "ID"] }, + "Solutions:SolutionVersion": { "Fn::FindInMap": ["Solution", "Data", "Version"] }, + "Solutions:SolutionName": { "Fn::FindInMap": ["Solution", "Data", "SolutionName"] }, + "Solutions:ApplicationType": { "Fn::FindInMap": ["Solution", "Data", "ApplicationType"] } + } + }, + }, + "DefaultApplicationAttributes": { + "Type": "AWS::ServiceCatalogAppRegistry::AttributeGroup", + "Properties": { + "Attributes": { + "SolutionID": { "Fn::FindInMap": ["Solution", "Data", "ID"] }, + "Version": { "Fn::FindInMap": ["Solution", "Data", "Version"] }, + "SolutionName": { "Fn::FindInMap": ["Solution", "Data", "SolutionName"] }, + "ApplicationType": { "Fn::FindInMap": ["Solution", "Data", "ApplicationType"] } + }, + "Description": "Attribute group for solution information", + "Name": { //This property has a 256 character limit + "Fn::Join": [ + "-", + [ + //attribute group names can not start with 'AWS', so prepend 'AttrGrp' + //this defends against errors thrown when stack names start with 'AWS' + "AttrGrp", + { "Ref": "AWS::StackName" } + ] + ] + } + } + }, + "AppRegistryApplicationAttributeAssociation": { + "Type" : "AWS::ServiceCatalogAppRegistry::AttributeGroupAssociation", + "Properties" : { + "Application" : { "Fn::GetAtt" : ["Application", "Id"] }, + "AttributeGroup" : { "Fn::GetAtt" : ["DefaultApplicationAttributes", "Id"] } + } + }, + //add resource association for the main stack + "AppRegistryApplicationStackAssociation": { + "Type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "Properties": { + "Application": { "Fn::GetAtt" : ["Application", "Id"] }, + "Resource": { "Ref": "AWS::StackId" }, + "ResourceType": "CFN_STACK" + } + }, + //add resource associations for each of the nested stacks + "AppRegistryApplicationStackAssociationExamples": { + "Type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "Condition": "BuildExamples", + "Properties": { + "Application": { "Fn::GetAtt" : ["Application", "Id"] }, + "Resource": { "Ref": "ExamplesStack" }, + "ResourceType": "CFN_STACK" + } + }, + "AppRegistryApplicationStackAssociationExport": { + "Type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "Properties": { + "Application": { "Fn::GetAtt" : ["Application", "Id"] }, + "Resource": { "Ref": "ExportStack" }, + "ResourceType": "CFN_STACK" + } + }, + "AppRegistryApplicationStackAssociationImport": { + "Type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "Properties": { + "Application": { "Fn::GetAtt" : ["Application", "Id"] }, + "Resource": { "Ref": "ImportStack" }, + "ResourceType": "CFN_STACK" + } + }, + "AppRegistryApplicationStackAssociationSagemakerEmbeddings": { + "Type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "Condition": "EmbeddingsSagemaker", + "Properties": { + "Application": { "Fn::GetAtt" : ["Application", "Id"] }, + "Resource": { "Ref": "SagemakerEmbeddingsStack" }, + "ResourceType": "CFN_STACK" + } + }, + "AppRegistryApplicationStackAssociationTestAll": { + "Type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation", + "Properties": { + "Application": { "Fn::GetAtt" : ["Application", "Id"] }, + "Resource": { "Ref": "TestAllStack" }, + "ResourceType": "CFN_STACK" + } + } +} \ No newline at end of file diff --git a/templates/master/cfn/handler.js b/templates/master/cfn/handler.js index e0c2d916a..55533b344 100644 --- a/templates/master/cfn/handler.js +++ b/templates/master/cfn/handler.js @@ -1,14 +1,13 @@ -var aws=require('aws-sdk') -aws.config.region=process.env.AWS_REGION -var s3=new aws.S3() +const { S3Client, HeadObjectCommand } = require("@aws-sdk/client-s3"); +const client = new S3Client({region: process.env.AWS_REGION}) exports.handler = function(event, context) { console.log(JSON.stringify(event,null,2)) if(event.RequestType!=="Delete"){ - s3.headObject({ + client.send(new HeadObjectCommand({ Bucket:event.ResourceProperties.Bucket, Key:event.ResourceProperties.Key - }).promise() + })) .then(result=>send(event, context, SUCCESS,{ version:result.VersionId ? result.VersionId : 1 })) @@ -19,6 +18,4 @@ exports.handler = function(event, context) { }else{ send(event, context, SUCCESS) } -} - - +} \ No newline at end of file diff --git a/templates/master/cfn/index.js b/templates/master/cfn/index.js index f8fbffe5a..b7c55516f 100644 --- a/templates/master/cfn/index.js +++ b/templates/master/cfn/index.js @@ -8,12 +8,13 @@ module.exports={ "Type": "AWS::Lambda::Function", "Properties": { "Code": { - "ZipFile":fs.readFileSync(__dirname+'/handler.js','utf-8' ) + fs.readFileSync(resplib,'utf-8') + //join files by new line to ensure valid javascript + "ZipFile":fs.readFileSync(__dirname+'/handler.js','utf-8' ) + "\n" + fs.readFileSync(resplib,'utf-8') }, "Handler": "index.handler", "MemorySize": "3008", "Role": {"Fn::GetAtt": ["CFNLambdaRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 60, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -55,7 +56,7 @@ module.exports={ "Handler": "index.handler", "MemorySize": "3008", "Role": {"Fn::GetAtt": ["CFNLambdaRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 180, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { diff --git a/templates/master/default-settings.js b/templates/master/default-settings.js index 0bbeb9e19..2a1eb3d3f 100644 --- a/templates/master/default-settings.js +++ b/templates/master/default-settings.js @@ -9,7 +9,8 @@ var default_settings = { ES_NO_HITS_QUESTION: 'no_hits', // The QID of the question when no answers could be found for a user's question ES_USE_FUZZY_MATCH: 'false', // Refer to https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-fuzzy-query.html ES_PHRASE_BOOST: '4', - ES_SCORE_ANSWER_FIELD: 'false', + ES_SCORE_ANSWER_FIELD: 'false', // If no 'qna' answer meets the score threshold, then query the answer field of qna items + ES_SCORE_TEXT_ITEM_PASSAGES: "true", // If no 'qna' answer meets the score threshold, then query the text field of 'text' items ENABLE_SENTIMENT_SUPPORT: 'true', //Determines whether to use Comprehend for sentiment analysis. Refer to https://docs.aws.amazon.com/comprehend/latest/dg/how-sentiment.html ENABLE_MULTI_LANGUAGE_SUPPORT: 'false', //User can override and set to true to Enable Multilanguage support ENABLE_CUSTOM_TERMINOLOGY: 'false', @@ -77,9 +78,27 @@ var default_settings = { LAMBDA_POSTPROCESS_HOOK: '', SEARCH_REPLACE_QUESTION_SUBSTRINGS: '', EMBEDDINGS_ENABLE: '${EMBEDDINGS_ENABLE}', // Set to TRUE or FALSE to enable or disable use of embeddings for semantic search - EMBEDDINGS_SCORE_THRESHOLD: 0.85, // If embedding similarity score is under threshold the match is rejected and QnABot reverts to scoring answer field (if ES_SCORE_ANSWER_FIELD is true) or Kendra fallback or no_hits - EMBEDDINGS_SCORE_ANSWER_THRESHOLD: 0.80, // Applies only when if ES_SCORE_ANSWER_FIELD is true. If embedding similarity score on answer field is under threshold the match is rejected and QnABot reverts to Kendra fallback or no_hits + EMBEDDINGS_SCORE_THRESHOLD: 0.85, // If embedding similarity score is under threshold the match is rejected and QnABot reverts to scoring answer field (if ES_SCORE_ANSWER_FIELD is true). + EMBEDDINGS_SCORE_ANSWER_THRESHOLD: 0.80, // Applies only when if ES_SCORE_ANSWER_FIELD is true. If embedding similarity score on answer field is under threshold the match is rejected. + EMBEDDINGS_TEXT_PASSAGE_SCORE_THRESHOLD: 0.80, // Applies only when if ES_SCORE_TEXT_ITEM_PASSAGES is true. If embedding similarity score on text item field is under threshold the match is rejected. + LLM_API: '${LLMApi}', + LLM_GENERATE_QUERY_ENABLE: '${LLM_GENERATE_QUERY_ENABLE}', + LLM_GENERATE_QUERY_PROMPT_TEMPLATE: '${LLM_GENERATE_QUERY_PROMPT_TEMPLATE}', + LLM_GENERATE_QUERY_MODEL_PARAMS: '${LLM_GENERATE_QUERY_MODEL_PARAMS}', + LLM_QA_ENABLE: '${LLM_QA_ENABLE}', // Set to TRUE or FALSE to enable or disable SAGEMAKER summarization + LLM_QA_USE_KENDRA_RETRIEVAL_API: '${LLM_QA_ENABLE}', + LLM_QA_PROMPT_TEMPLATE: '${LLM_QA_PROMPT_TEMPLATE}', + LLM_QA_MODEL_PARAMS: '${LLM_QA_MODEL_PARAMS}', + LLM_QA_PREFIX_MESSAGE: 'LLM Answer:', + LLM_QA_SHOW_CONTEXT_TEXT: "TRUE", + LLM_QA_SHOW_SOURCE_LINKS: "TRUE", + LLM_CHAT_HISTORY_MAX_MESSAGES: 12, + LLM_QA_NO_HITS_REGEX: 'Sorry, //remove comment to enable custom no match (no_hits) when LLM does not know the answer.', }; +const defaultGenerateQueryPromptTemplate = 'Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question.
Chat History:
{history}
Follow Up Input: {input}
Standalone question:'; +const defaultQAPromptTemplate = `Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer. Write the answer in up to 5 complete sentences.

{context}

Question: {query}
Helpful Answer:`; +const defaultModelParams = `{\\"temperature\\":0.01, \\"return_full_text\\":false, \\"max_new_tokens\\": 150}`; + module.exports = { "DefaultUserPoolJwksUrl": { "Type": "AWS::SSM::Parameter", @@ -94,10 +113,17 @@ module.exports = { "Properties": { "Description": "Default QnABot Settings - DO NOT MODIFY", "Type": "String", + "Tier": "Advanced", // Advanced tier required to accomodate number of settings "Value": { "Fn::Sub" : [ JSON.stringify(default_settings), { "ES_USE_KEYWORD_FILTERS" : {"Fn::If": ["EmbeddingsEnable", "FALSE", "TRUE"]}, - "EMBEDDINGS_ENABLE" : {"Fn::If": ["EmbeddingsEnable", "TRUE", "FALSE"]} + "EMBEDDINGS_ENABLE" : {"Fn::If": ["EmbeddingsEnable", "TRUE", "FALSE"]}, + "LLM_GENERATE_QUERY_ENABLE" : {"Fn::If": ["LLMEnable", "TRUE", "FALSE"]}, + "LLM_QA_ENABLE" : {"Fn::If": ["LLMEnable", "TRUE", "FALSE"]}, + "LLM_GENERATE_QUERY_PROMPT_TEMPLATE": defaultGenerateQueryPromptTemplate, + "LLM_QA_PROMPT_TEMPLATE": defaultQAPromptTemplate, + "LLM_GENERATE_QUERY_MODEL_PARAMS": defaultModelParams, + "LLM_QA_MODEL_PARAMS": defaultModelParams, } ]} } diff --git a/templates/master/elasticsearch/index_mappings.js b/templates/master/elasticsearch/index_mappings.js index 047d10a14..04bb32086 100644 --- a/templates/master/elasticsearch/index_mappings.js +++ b/templates/master/elasticsearch/index_mappings.js @@ -1,8 +1,10 @@ module.exports={ properties:{ + // all doc types have qid qid:{ type:"keyword" }, + // 'qna' doc type fields quniqueterms: { type: "text", analyzer: "custom_english_unique" @@ -37,7 +39,7 @@ module.exports={ "space_type": "cosinesimil", "engine": "nmslib" } - }, + }, t:{ type:'text',analyzer:"whitespace" }, @@ -50,7 +52,20 @@ module.exports={ l:{ type:"keyword" }, - // quiz type fields + // 'text' doc type fields + passage:{ + type:'text',analyzer:"custom_english" + }, + passage_vector: { + "type": "knn_vector", + "dimension": '${EmbeddingsDimensions}', + "method": { + "name": "hnsw", + "space_type": "cosinesimil", + "engine": "nmslib" + } + }, + // 'quiz' doc type fields question:{ type:"text", analyzer:"custom_english" diff --git a/templates/master/elasticsearch/info.js b/templates/master/elasticsearch/info.js index 3ca56cd46..ac11cfd23 100644 --- a/templates/master/elasticsearch/info.js +++ b/templates/master/elasticsearch/info.js @@ -22,7 +22,7 @@ module.exports={ "Handler": "index.handler", "MemorySize": "128", "Role": {"Fn::GetAtt": ["ESProxyLambdaRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -34,6 +34,9 @@ module.exports={ "Fn::If": [ "XRAYEnabled", {"Mode": "Active"}, {"Ref" : "AWS::NoValue"} ] }, + "Layers":[ + {"Ref":"AwsSdkLayerLambdaLayer"} + ], "Tags":[{ Key:"Type", Value:"CustomResource" diff --git a/templates/master/elasticsearch/proxy.js b/templates/master/elasticsearch/proxy.js index 9733a73f2..fd5f3ab78 100644 --- a/templates/master/elasticsearch/proxy.js +++ b/templates/master/elasticsearch/proxy.js @@ -24,7 +24,7 @@ module.exports={ "Handler": "resource.handler", "MemorySize": "1408", "Role": {"Fn::GetAtt": ["ESProxyLambdaRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -84,21 +84,21 @@ module.exports={ { "EmbeddingsDimensions" : { "Fn::If": [ - "EmbeddingsEnable", + "EmbeddingsEnable", { "Fn::If": [ - "EmbeddingsSagemaker", + "EmbeddingsSagemaker", "1024", { "Fn::If": [ - "EmbeddingsLambda", + "EmbeddingsLambda", {"Ref": "EmbeddingsLambdaDimensions"}, - "INVALID EMBEDDINGS API - Cannot determine dimensions" + "INVALID EMBEDDINGS API - Cannot determine dimensions" ] } ] - }, + }, "1" // minimal default to use if embeddings are disabled ] } diff --git a/templates/master/examples.js b/templates/master/examples.js index 0f7ed3f46..314cb4732 100644 --- a/templates/master/examples.js +++ b/templates/master/examples.js @@ -25,6 +25,7 @@ module.exports={ "XraySetting":{"Ref": "XraySetting"}, "DefaultQnABotSettings": {"Ref":"DefaultQnABotSettings"}, "InstallLexResponseBots": {"Ref": "InstallLexResponseBots"}, + "AwsSdkLayerLambdaLayer":{"Ref":"AwsSdkLayerLambdaLayer"}, } } } diff --git a/templates/master/index.js b/templates/master/index.js index f907227b3..7c5d2128a 100644 --- a/templates/master/index.js +++ b/templates/master/index.js @@ -12,8 +12,18 @@ module.exports={ "Resources":_.assign.apply({},files), "Conditions": {}, "AWSTemplateFormatVersion": "2010-09-09", - "Description": `(SO0189-ext) QnABot with admin and client websites - (Version v${process.env.npm_package_version})`, - "Mappings": {}, + "Description": `(SO0189-ext) QnABot with admin and client websites - Version v${process.env.npm_package_version}`, + "Mappings": { + "Solution": { + "Data": { + "ID": "SO0189", + "Version": process.env.npm_package_version, + "AppRegistryApplicationName": "qnabot", + "SolutionName": "QnABot on AWS", + "ApplicationType": "AWS-Solutions" + } + } + }, "Outputs": { "CognitoEndpoint":{ "Value":{"Fn::GetAtt":["DesignerLogin","Domain"]} @@ -257,7 +267,7 @@ module.exports={ "Type":"String", "AllowedValues" : ["true", "false"], "Default":"true" - }, + }, "XraySetting":{ "Type":"String", "Description": "Configure Lambdas with X-Ray enabled", @@ -293,6 +303,30 @@ module.exports={ "MinValue":1, "Description":"Optional: If EmbeddingsApi is LAMBDA, provide number of dimensions for embeddings returned by the EmbeddingsLambda function specified above.", "Default":4096 + }, + 'LLMApi':{ + 'Type':'String', + 'Description':'Optionally enable (experimental) QnABot question disambiguation and generative question answering using an LLM. If set to SAGEMAKER, a Sagemaker endpoint is automatically provisioned. To use a custom LAMBDA function, provide additional parameters below.', + 'AllowedValues': ['DISABLED', 'SAGEMAKER', 'LAMBDA'], + 'Default':'DISABLED' + }, + 'LLMSagemakerInstanceType':{ + 'Type':'String', + 'AllowedPattern':'^ml.*$', + 'Description':'Optional: If LLMApi is SAGEMAKER, provide the SageMaker endpoint instance type. Defaults to ml.g5.12xlarge. Check account and region availability through the Service Quotas service before deploying', + 'Default':'ml.g5.12xlarge' + }, + 'LLMSagemakerInitialInstanceCount':{ + 'Type':'Number', + 'MinValue':1, + 'Description':'Optional: If LLMApi is SAGEMAKER, provide initial instance count. Serverless Inference is not currently available for the built-in LLM model.', + 'Default':1 + }, + 'LLMLambdaArn':{ + 'Type':'String', + 'AllowedPattern': '^(|arn:aws:lambda:.*)$', + 'Description':'Optional: If LLMApi is LAMBDA, provide ARN for a Lambda function that takes JSON {"prompt":"string", "settings":{key:value,..}}, and returns JSON {"generated_text":"string"}', + 'Default':'' } }, "Conditions":{ @@ -317,6 +351,10 @@ module.exports={ "EmbeddingsEnable":{"Fn::Not": [{ "Fn::Equals":[{"Ref":"EmbeddingsApi"},"DISABLED"]}]}, "EmbeddingsSagemaker":{"Fn::Equals":[{"Ref":"EmbeddingsApi"},"SAGEMAKER"]}, "EmbeddingsLambda":{"Fn::Equals":[{"Ref":"EmbeddingsApi"},"LAMBDA"]}, - "EmbeddingsLambdaArn":{"Fn::Not": [{ "Fn::Equals":[{"Ref":"EmbeddingsLambdaArn"},""]}]} + "EmbeddingsLambdaArn":{"Fn::Not": [{ "Fn::Equals":[{"Ref":"EmbeddingsLambdaArn"},""]}]}, + 'LLMEnable':{'Fn::Not': [{ 'Fn::Equals':[{'Ref':'LLMApi'},'DISABLED']}]}, + "LLMSagemaker":{"Fn::Equals":[{"Ref":"LLMApi"},"SAGEMAKER"]}, + "LLMLambda":{"Fn::Equals":[{"Ref":"LLMApi"},"LAMBDA"]}, + 'LLMLambdaArn':{'Fn::Not': [{ 'Fn::Equals':[{'Ref':'LLMLambdaArn'},'']}]}, } } \ No newline at end of file diff --git a/templates/master/lambda-layers.js b/templates/master/lambda-layers.js index ebb889b3e..d8eb6db3d 100644 --- a/templates/master/lambda-layers.js +++ b/templates/master/lambda-layers.js @@ -32,7 +32,7 @@ module.exports = { }, S3ObjectVersion: { Ref: "CommonModulesLayerCodeVersion" }, }, - CompatibleRuntimes: ["nodejs16.x"], + CompatibleRuntimes: [process.env.npm_package_config_lambdaRuntime], }, }, QnABotCommonLayerCodeVersion: { @@ -68,7 +68,7 @@ module.exports = { }, S3ObjectVersion: { Ref: "QnABotCommonLayerCodeVersion" }, }, - CompatibleRuntimes: ["nodejs16.x"], + CompatibleRuntimes: [process.env.npm_package_config_lambdaRuntime], }, }, AwsSdkLayerCodeVersion: { @@ -86,7 +86,7 @@ module.exports = { Content: { S3Bucket: { Ref: "BootstrapBucket" }, S3Key: { "Fn::Sub": "${BootstrapPrefix}/lambda/aws-sdk-layer.zip" }, - S3ObjectVersion: { Ref: "AwsSdkLayerCodeVersion" }, + S3ObjectVersion: { Ref: "AwsSdkLayerCodeVersion" } }, LayerName:{ "Fn::Join": [ @@ -102,7 +102,7 @@ module.exports = { ], ], }, - CompatibleRuntimes: ["nodejs16.x"], + CompatibleRuntimes: [process.env.npm_package_config_lambdaRuntime], }, }, CfnLambdaLayerCodeVersion: { @@ -136,7 +136,7 @@ module.exports = { S3Key: { "Fn::Sub": "${BootstrapPrefix}/lambda/cfn-lambda-layer.zip" }, S3ObjectVersion: { Ref: "CfnLambdaLayerCodeVersion" }, }, - CompatibleRuntimes: ["nodejs16.x"], + CompatibleRuntimes: [process.env.npm_package_config_lambdaRuntime], }, }, EsProxyLayerCodeVersion: { @@ -170,7 +170,7 @@ module.exports = { S3Key: { "Fn::Sub": "${BootstrapPrefix}/lambda/es-proxy-layer.zip" }, S3ObjectVersion: { Ref: "EsProxyLayerCodeVersion" }, }, - CompatibleRuntimes: ["nodejs16.x"], + CompatibleRuntimes: [process.env.npm_package_config_lambdaRuntime], }, }, }; diff --git a/templates/master/lambda.js b/templates/master/lambda.js index 6baa130d3..c9a995446 100644 --- a/templates/master/lambda.js +++ b/templates/master/lambda.js @@ -20,47 +20,8 @@ _.forEach(_.assign.apply({},files),(value,key)=>{ }) module.exports=Object.assign( - _.fromPairs(lambdas), -{"LambdaAccessRole": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Principal": { - "Service": "apigateway.amazonaws.com" - }, - "Action": "sts:AssumeRole" - } - ] - }, - "Path": "/", - "Policies": [ - util.basicLambdaExecutionPolicy(), - util.lambdaVPCAccessExecutionRole(), - util.xrayDaemonWriteAccess(), - { - "PolicyName" : "LambdaPolicy", - "PolicyDocument" : { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "lambda:*" - ], - "Resource":["*"] - } - ] - } - } - ] - }, - "Metadata": util.cfnNag(["W11", "W12", "F3"]) - }, -}) + _.fromPairs(lambdas) +) function permission(name){ return { diff --git a/templates/master/lex-build/index.js b/templates/master/lex-build/index.js index 0b7ad88b8..c3891d581 100644 --- a/templates/master/lex-build/index.js +++ b/templates/master/lex-build/index.js @@ -22,7 +22,7 @@ module.exports = { LEXV2_BUILD_LAMBDA: { "Ref": "Lexv2BotLambda" }, ADDRESS: { "Fn::Join": ["", ["https://", { "Fn::GetAtt": ["ESVar", "ESAddress"] }]] }, INDEX: { "Fn::GetAtt": ["Var", "index"] }, - }, "nodejs16.x"), + }, process.env.npm_package_config_lambdaRuntime), "LexBuildLambdaStart": lambda({ "ZipFile": fs.readFileSync(__dirname + '/start.js', 'utf8') }, { @@ -30,14 +30,14 @@ module.exports = { STATUS_KEY: { "Fn::If": ["CreateLexV1Bots", "status.json", { "Ref": "AWS::NoValue" }] }, LEXV2_STATUS_KEY: "lexV2status.json", BUILD_FUNCTION: { "Fn::GetAtt": ["LexBuildLambda", "Arn"] } - }), + }, process.env.npm_package_config_lambdaRuntime), "LexBuildLambdaPoll": lambda({ "ZipFile": fs.readFileSync(__dirname + '/poll.js', 'utf8') }, { STATUS_KEY: { "Fn::If": ["CreateLexV1Bots", "status.json", { "Ref": "AWS::NoValue" }] }, STATUS_BUCKET: { "Ref": "BuildStatusBucket" }, BOT_NAME: { "Fn::If": ["CreateLexV1Bots", { "Ref": "LexBot" }, { "Ref": "AWS::NoValue" }] }, - }), + }, process.env.npm_package_config_lambdaRuntime), "LexBuildCodeVersion": { "Type": "Custom::S3Version", "Properties": { @@ -206,7 +206,7 @@ module.exports = { } }; -function lambda(code, variable = {}, runtime = "nodejs16.x") { +function lambda(code, variable, runtime) { return { "Type": "AWS::Lambda::Function", "Properties": { @@ -229,6 +229,9 @@ function lambda(code, variable = {}, runtime = "nodejs16.x") { "Fn::If": ["XRAYEnabled", { "Mode": "Active" }, { "Ref": "AWS::NoValue" }] }, + "Layers":[ + {"Ref":"AwsSdkLayerLambdaLayer"} + ], "Tags": [{ Key: "Type", Value: "Api" diff --git a/templates/master/lex/bot.js b/templates/master/lex/bot.js index 454fcf0e8..f8d01e0a6 100644 --- a/templates/master/lex/bot.js +++ b/templates/master/lex/bot.js @@ -10,7 +10,7 @@ module.exports={ "Properties": { "Action": "lambda:InvokeFunction", "FunctionName": { "Fn::Join": [ ":", [ - {"Fn::GetAtt":["FulfillmentLambda","Arn"]}, + {"Fn::GetAtt":["FulfillmentLambda","Arn"]}, "live" ]]}, "Principal": "lex.amazonaws.com" @@ -51,7 +51,7 @@ module.exports={ "type": "CodeHook", "codeHook": { "uri": { "Fn::Join": [ ":", [ - {"Fn::GetAtt":["FulfillmentLambda","Arn"]}, + {"Fn::GetAtt":["FulfillmentLambda","Arn"]}, "live" ]]}, "messageVersion": "1.0" @@ -74,7 +74,7 @@ module.exports={ "type": "CodeHook", "codeHook": { "uri": { "Fn::Join": [ ":", [ - {"Fn::GetAtt":["FulfillmentLambda","Arn"]}, + {"Fn::GetAtt":["FulfillmentLambda","Arn"]}, "live" ]]}, "messageVersion": "1.0" diff --git a/templates/master/lex/fulfillment.js b/templates/master/lex/fulfillment.js index 1aeee13de..96aefe77f 100644 --- a/templates/master/lex/fulfillment.js +++ b/templates/master/lex/fulfillment.js @@ -71,6 +71,16 @@ module.exports = { }, EMBEDDINGS_SAGEMAKER_INSTANCECOUNT : { "Ref": "SagemakerInitialInstanceCount" }, EMBEDDINGS_LAMBDA_ARN: { "Ref": "EmbeddingsLambdaArn" }, + LLM_API: { "Ref": "LLMApi" }, + LLM_SAGEMAKERENDPOINT : { + "Fn::If": [ + "LLMSagemaker", + {"Fn::GetAtt": ["SageMakerQASummarizeLLMStack", "Outputs.LLMSagemakerEndpoint"] }, + "" + ] + }, + LLM_SAGEMAKERINSTANCECOUNT : { "Ref": "LLMSagemakerInitialInstanceCount" }, // force new fn version when instance count changes + LLM_LAMBDA_ARN: { "Ref": "LLMLambdaArn" }, }, examples, responsebots) }, "Handler": "index.handler", @@ -82,7 +92,7 @@ module.exports = { ], "MemorySize": 1408, "Role": {"Fn::GetAtt": ["FulfillmentLambdaRole", "Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "TracingConfig": { "Mode": { @@ -140,6 +150,16 @@ module.exports = { "" ]}, {"Ref": "EmbeddingsLambdaArn"} + ], + "QASummarizeTrigger": [ + {"Ref": "LLMApi"}, + {"Ref": "SagemakerInitialInstanceCount"}, + {"Fn::If": [ + "LLMSagemaker", + {"Fn::GetAtt": ["SageMakerQASummarizeLLMStack", "Outputs.LLMSagemakerEndpoint"] }, + "" + ]}, + {"Ref": "LLMLambdaArn"} ] } } @@ -178,6 +198,7 @@ module.exports = { { "Fn::GetAtt": ["ESLoggingLambda", "Arn"] }, { "Fn::GetAtt": ["ESQidLambda", "Arn"] }, { "Fn::If": ["EmbeddingsLambdaArn", {"Ref":"EmbeddingsLambdaArn"}, {"Ref":"AWS::NoValue"}] }, + { "Fn::If": ["LLMLambdaArn", {"Ref":"LLMLambdaArn"}, {"Ref":"AWS::NoValue"}] }, ].concat(require('../../examples/outputs').names .map(x => { return { "Fn::GetAtt": ["ExamplesStack", `Outputs.${x}`] } @@ -300,7 +321,7 @@ module.exports = { "Fn::If": [ "EmbeddingsSagemaker", { - "PolicyName" : "SagemakerInvokeEndpointAccess", + "PolicyName" : "EmbeddingsSagemakerInvokeEndpointAccess", "PolicyDocument" : { "Version": "2012-10-17", "Statement": [ @@ -317,6 +338,27 @@ module.exports = { {"Ref":"AWS::NoValue"} ] }, + { + "Fn::If": [ + "LLMSagemaker", + { + "PolicyName" : "LLMSagemakerInvokeEndpointAccess", + "PolicyDocument" : { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "sagemaker:InvokeEndpoint" + ], + "Resource": {"Fn::GetAtt": ["SageMakerQASummarizeLLMStack", "Outputs.LLMSagemakerEndpointArn"]} + } + ] + } + }, + {"Ref":"AWS::NoValue"} + ] + }, { "PolicyName" : "S3QNABucketReadAccess", "PolicyDocument" : { @@ -360,7 +402,7 @@ module.exports = { "Handler": "index.warmer", "MemorySize": "512", "Role": { "Fn::GetAtt": ["WarmerLambdaRole", "Arn"] }, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "Layers": [ {"Ref": "AwsSdkLayerLambdaLayer"}, diff --git a/templates/master/lexv2-build/index.js b/templates/master/lexv2-build/index.js index 376d7ef66..64396575e 100644 --- a/templates/master/lexv2-build/index.js +++ b/templates/master/lexv2-build/index.js @@ -15,7 +15,7 @@ module.exports={ ]]}, LOCALES:{"Ref":"LexV2BotLocaleIds"}, PYTHONPATH:"/var/task/py_modules:/var/runtime:/opt/python" - },"python3.9"), + },process.env.npm_package_config_pythonRuntime), "Lexv2BotCodeVersion":{ "Type": "Custom::S3Version", "Properties": { @@ -125,7 +125,7 @@ module.exports={ } } -function lambda(code,variable={},runtime="nodejs16.x"){ +function lambda(code, variable, runtime){ return { "Type": "AWS::Lambda::Function", "Properties": { diff --git a/templates/master/proxy-es.js b/templates/master/proxy-es.js index 32eb47f72..8e617bbd4 100644 --- a/templates/master/proxy-es.js +++ b/templates/master/proxy-es.js @@ -41,7 +41,7 @@ module.exports={ "Handler": "index.utterances", "MemorySize": "1408", "Role": {"Fn::GetAtt": ["ESProxyLambdaRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -69,7 +69,7 @@ module.exports={ "S3ObjectVersion":{"Ref":"ESProxyCodeVersion"} }, "Layers":[{"Ref":"AwsSdkLayerLambdaLayer"}, - {"Ref":"CommonModulesLambdaLayer"}, + {"Ref":"CommonModulesLambdaLayer"}, {"Ref":"EsProxyLambdaLayer"}, {"Ref":"QnABotCommonLambdaLayer"}], "Environment": { @@ -85,7 +85,7 @@ module.exports={ "Handler": "index.qid", "MemorySize": "1408", "Role": {"Fn::GetAtt": ["ESProxyLambdaRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -127,7 +127,7 @@ module.exports={ "Handler": "index.cleanmetrics", "MemorySize": "1408", "Role": {"Fn::GetAtt": ["ESProxyLambdaRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -188,7 +188,7 @@ module.exports={ "Handler": "index.logging", "MemorySize": "1408", "Role": {"Fn::GetAtt": ["ESLoggingLambdaRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -228,7 +228,7 @@ module.exports={ "Handler": "index.query", "MemorySize": "1408", "Role": {"Fn::GetAtt": ["ESProxyLambdaRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -270,8 +270,8 @@ module.exports={ EMBEDDINGS_API: { "Ref": "EmbeddingsApi" }, EMBEDDINGS_SAGEMAKER_ENDPOINT : { "Fn::If": [ - "EmbeddingsSagemaker", - {"Fn::GetAtt": ["SagemakerEmbeddingsStack", "Outputs.EmbeddingsSagemakerEndpoint"] }, + "EmbeddingsSagemaker", + {"Fn::GetAtt": ["SagemakerEmbeddingsStack", "Outputs.EmbeddingsSagemakerEndpoint"] }, "" ] }, @@ -281,7 +281,7 @@ module.exports={ "Handler": "index.handler", "MemorySize": "1408", "Role": {"Fn::GetAtt": ["ESProxyLambdaRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -336,7 +336,7 @@ module.exports={ }] } }, - { + { "Fn::If": [ "EmbeddingsEnable", { @@ -344,9 +344,9 @@ module.exports={ "PolicyDocument" : { "Version": "2012-10-17", "Statement": [ - { + { "Fn::If": [ - "EmbeddingsSagemaker", + "EmbeddingsSagemaker", { "Effect": "Allow", "Action": [ @@ -357,9 +357,9 @@ module.exports={ {"Ref":"AWS::NoValue"} ] }, - { + { "Fn::If": [ - "EmbeddingsLambdaArn", + "EmbeddingsLambdaArn", { "Effect": "Allow", "Action": [ @@ -493,7 +493,8 @@ module.exports={ },{ "Effect": "Allow", "Action": [ - "kendra:Query" + "kendra:Query", + "kendra:Retrieve" ], "Resource":[ {"Fn::Sub":"arn:aws:kendra:${AWS::Region}:${AWS::AccountId}:index/*"}, diff --git a/templates/master/proxy-lex/index.js b/templates/master/proxy-lex/index.js index d36b42822..fd37bde57 100644 --- a/templates/master/proxy-lex/index.js +++ b/templates/master/proxy-lex/index.js @@ -11,7 +11,7 @@ module.exports={ "Handler": "index.handler", "MemorySize": "128", "Role": {"Fn::GetAtt": ["LexProxyLambdaRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -23,6 +23,9 @@ module.exports={ "Fn::If": [ "XRAYEnabled", {"Mode": "Active"}, {"Ref" : "AWS::NoValue"} ] }, + "Layers":[ + {"Ref":"AwsSdkLayerLambdaLayer"} + ], "Tags":[{ Key:"Type", Value:"Api" @@ -61,7 +64,7 @@ module.exports={ "Handler": "index.handler", "MemorySize": "128", "Role": {"Fn::GetAtt": ["LexProxyLambdaRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -73,6 +76,9 @@ module.exports={ "Fn::If": [ "XRAYEnabled", {"Mode": "Active"}, {"Ref" : "AWS::NoValue"} ] }, + "Layers":[ + {"Ref":"AwsSdkLayerLambdaLayer"} + ], "Tags":[{ Key:"Type", Value:"Api" diff --git a/templates/master/proxy-lex/test.js b/templates/master/proxy-lex/test.js index bf868ef22..a63fc5db7 100644 --- a/templates/master/proxy-lex/test.js +++ b/templates/master/proxy-lex/test.js @@ -1,6 +1,6 @@ -process.env.AWS_PROFILE=require('../../../config').profile -process.env.AWS_DEFAULT_REGION=require('../../../config').region -process.env.AWS_REGION=require('../../../config').region +process.env.AWS_PROFILE=require('../../../config.json').profile +process.env.AWS_DEFAULT_REGION=require('../../../config.json').region +process.env.AWS_REGION=require('../../../config.json').region var handler=require('./handler').handler module.exports={ diff --git a/templates/master/routes/bot/index.js b/templates/master/routes/bot/index.js index 902ae432c..07074f546 100644 --- a/templates/master/routes/bot/index.js +++ b/templates/master/routes/bot/index.js @@ -37,48 +37,9 @@ module.exports={ "Path":"/bot" }, "Properties" :JSON.stringify({ - description:"" + description:"" }), "RestApiId" : {"Ref":"API"} } } } -function config(opts){ - return { - "Type": "AWS::ApiGateway::Method", - "Properties": { - "AuthorizationType": "AWS_IAM", - "HttpMethod":opts.method, - "Integration":_.pickBy({ - "Type": "AWS", - "IntegrationHttpMethod":opts.method, - "Credentials":{"Fn::GetAtt":["LambdaAccessRole","Arn"]}, - "Uri": {"Fn::Join": ["",[ - "arn:aws:apigateway:", - {"Ref": "AWS::Region"}, - ":lambda:path/2015-03-31/functions/", - { "Fn::Join": [ ":", [ - {"Fn::GetAtt":["FulfillmentLambda","Arn"]}, - "live" - ]]}, - "/configuration" - ]]}, - "IntegrationResponses": [{ - "StatusCode":200, - "ResponseTemplates":{ - "application/json":{"Fn::Sub":opts.response} - } - }], - "RequestTemplates":opts.request ? { - "application/json":{"Fn::Sub":opts.request} - } : null - }), - "ResourceId":{"Ref":"Hooks"}, - "MethodResponses": [ - {"StatusCode": 200}, - {"StatusCode": 400} - ], - "RestApiId": {"Ref": "API"} - } - } -} diff --git a/templates/master/routes/examples/index.js b/templates/master/routes/examples/index.js index c75dfce96..0be3fa1fc 100644 --- a/templates/master/routes/examples/index.js +++ b/templates/master/routes/examples/index.js @@ -79,7 +79,7 @@ module.exports={ "Handler": "index.documents", "MemorySize": "128", "Role": {"Fn::GetAtt": ["S3ListLambdaRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -91,6 +91,9 @@ module.exports={ "Fn::If": [ "XRAYEnabled", {"Mode": "Active"}, {"Ref" : "AWS::NoValue"} ] }, + "Layers":[ + {"Ref":"AwsSdkLayerLambdaLayer"} + ], "Tags":[{ Key:"Type", Value:"Api" @@ -107,7 +110,7 @@ module.exports={ "Handler": "index.photos", "MemorySize": "128", "Role": {"Fn::GetAtt": ["S3ListLambdaRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -119,6 +122,9 @@ module.exports={ "Fn::If": [ "XRAYEnabled", {"Mode": "Active"}, {"Ref" : "AWS::NoValue"} ] }, + "Layers":[ + {"Ref":"AwsSdkLayerLambdaLayer"} + ], "Tags":[{ Key:"Type", Value:"Api" diff --git a/templates/master/routes/jobs/index.js b/templates/master/routes/jobs/index.js index 05bd3f68c..94900a008 100644 --- a/templates/master/routes/jobs/index.js +++ b/templates/master/routes/jobs/index.js @@ -143,7 +143,7 @@ module.exports={ "Handler": "index.handler", "MemorySize": "128", "Role": {"Fn::GetAtt": ["S3ListLambdaRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -155,6 +155,9 @@ module.exports={ "Fn::If": [ "XRAYEnabled", {"Mode": "Active"}, {"Ref" : "AWS::NoValue"} ] }, + "Layers":[ + {"Ref":"AwsSdkLayerLambdaLayer"} + ], "Tags":[{ Key:"Type", Value:"Api" diff --git a/templates/master/routes/qa/single/get.vm b/templates/master/routes/qa/single/get.vm index 2d93c5af5..fbef6d9a1 100644 --- a/templates/master/routes/qa/single/get.vm +++ b/templates/master/routes/qa/single/get.vm @@ -47,6 +47,12 @@ "score_answer": "", #end + #if ($input.params('score_text_passage')) + "score_text_passage": "$util.urlDecode($input.params('score_text_passage'))", + #else + "score_text_passage": "", + #end + "size":"$perpage", "from":"$from", diff --git a/templates/master/sagemaker-qa-summarize-llm-stack.js b/templates/master/sagemaker-qa-summarize-llm-stack.js new file mode 100644 index 000000000..a3248439e --- /dev/null +++ b/templates/master/sagemaker-qa-summarize-llm-stack.js @@ -0,0 +1,18 @@ +module.exports={ + "SageMakerQASummarizeLLMStack":{ + "Type" : "AWS::CloudFormation::Stack", + "Condition":"LLMSagemaker", + "Properties" : { + "TemplateURL" :{"Fn::Sub":"https://${BootstrapBucket}.s3.${AWS::Region}.amazonaws.com/${BootstrapPrefix}/templates/sagemaker-qa-summarize-llm.json"}, + "Parameters" :{ + "CFNLambda":{"Fn::GetAtt":["CFNLambda","Arn"]}, + "BootstrapBucket":{"Ref":"BootstrapBucket"}, + "BootstrapPrefix":{"Ref":"BootstrapPrefix"}, + "SagemakerInstanceType":{"Ref":"LLMSagemakerInstanceType"}, + "SagemakerInitialInstanceCount":{"Ref":"LLMSagemakerInitialInstanceCount"}, + "VPCSubnetIdList":{"Fn::Join":[",",{"Ref":"VPCSubnetIdList"}]}, + "VPCSecurityGroupIdList":{"Fn::Join":[",",{"Ref":"VPCSecurityGroupIdList"}]}, + } + } + } +} \ No newline at end of file diff --git a/templates/master/schemaLambda.js b/templates/master/schemaLambda.js index ab8570ac1..c8a1fd429 100644 --- a/templates/master/schemaLambda.js +++ b/templates/master/schemaLambda.js @@ -21,7 +21,7 @@ module.exports={ "Handler": "index.handler", "MemorySize": "128", "Role": {"Fn::GetAtt": ["SchemaLambdaRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -33,6 +33,9 @@ module.exports={ "Fn::If": [ "XRAYEnabled", {"Mode": "Active"}, {"Ref" : "AWS::NoValue"} ] }, + "Layers":[ + {"Ref":"AwsSdkLayerLambdaLayer"} + ], "Tags":[{ Key:"Type", Value:"Api" diff --git a/templates/master/signup/index.js b/templates/master/signup/index.js index e0e7c19bb..5b608d435 100644 --- a/templates/master/signup/index.js +++ b/templates/master/signup/index.js @@ -43,7 +43,7 @@ module.exports={ "Arn" ] }, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -55,6 +55,9 @@ module.exports={ "Fn::If": [ "XRAYEnabled", {"Mode": "Active"}, {"Ref" : "AWS::NoValue"} ] }, + "Layers":[ + {"Ref":"AwsSdkLayerLambdaLayer"} + ], "Tags":[{ Key:"Type", Value:"Cognito" @@ -86,7 +89,7 @@ module.exports={ "Arn" ] }, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 300, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -98,6 +101,9 @@ module.exports={ "Fn::If": [ "XRAYEnabled", {"Mode": "Active"}, {"Ref" : "AWS::NoValue"} ] }, + "Layers":[ + {"Ref":"AwsSdkLayerLambdaLayer"} + ], "Tags":[{ Key:"Type", Value:"Cognito" diff --git a/templates/master/test/index.js b/templates/master/test/index.js index 9781feaec..e26367381 100644 --- a/templates/master/test/index.js +++ b/templates/master/test/index.js @@ -1,4 +1,4 @@ -var config=require('../../../config') +var config=require('../../../config.json') process.env.AWS_PROFILE=config.profile process.env.AWS_DEFAULT_REGION=config.region diff --git a/templates/master/test/lex.js b/templates/master/test/lex.js index 2cd44dc0d..d67388ab9 100644 --- a/templates/master/test/lex.js +++ b/templates/master/test/lex.js @@ -1,4 +1,4 @@ -var config = require('../../../config') +var config = require('../../../config.json') process.env.AWS_PROFILE = config.profile process.env.AWS_DEFAULT_REGION = config.region var query = require('query-string').stringify @@ -18,7 +18,7 @@ var api = require('./util').api module.exports = { - + setUp: function(cb) { var self = this outputs('dev/master').then(function(output) { @@ -219,7 +219,7 @@ module.exports = { navigation1: async function(test) { try { var args = await outputs('dev/master') - + await api({ path: "questions/navigation.1", method: "PUT", @@ -250,7 +250,7 @@ module.exports = { console.log(response) sessionAttributes = response.sessionAttributes test.equal(response.message, "Unable to go to the next room...") - + response = await this.lex.postText({ sessionAttributes: sessionAttributes, inputText: "previous" @@ -258,7 +258,7 @@ module.exports = { console.log(response) sessionAttributes = response.sessionAttributes test.equal(response.message, "Unable to go to the previous room...") - + } catch (e) { test.ifError(e) @@ -312,7 +312,7 @@ module.exports = { next: "navigation.4" } }) - + await api({ path: "questions/navigation.4", method: "PUT", @@ -354,7 +354,7 @@ module.exports = { console.log(response) sessionAttributes = response.sessionAttributes test.equal(response.message, "One") - + response = await this.lex.postText({ sessionAttributes:sessionAttributes, inputText: "Two" @@ -362,7 +362,7 @@ module.exports = { console.log(response) sessionAttributes = response.sessionAttributes test.equal(response.message, "Two") - + response = await this.lex.postText({ sessionAttributes:sessionAttributes, inputText: "next" @@ -370,7 +370,7 @@ module.exports = { console.log(response) sessionAttributes = response.sessionAttributes test.equal(response.message, "Three") - + response = await this.lex.postText({ sessionAttributes:sessionAttributes, inputText: "previous" @@ -378,7 +378,7 @@ module.exports = { console.log(response) sessionAttributes = response.sessionAttributes test.equal(response.message, "Two") - + response = await this.lex.postText({ sessionAttributes:sessionAttributes, inputText: "Two" @@ -386,7 +386,7 @@ module.exports = { console.log(response) sessionAttributes = response.sessionAttributes test.equal(response.message, "Two") - + response = await this.lex.postText({ sessionAttributes:sessionAttributes, inputText: "previous" @@ -394,7 +394,7 @@ module.exports = { console.log(response) sessionAttributes = response.sessionAttributes test.equal(response.message, "One") - + } catch (e) { test.ifError(e) @@ -516,7 +516,7 @@ module.exports = { console.log(response) sessionAttributes = response.sessionAttributes test.equal(response.message, "One") - + response = await this.lex.postText({ sessionAttributes:sessionAttributes, inputText: "next" @@ -524,7 +524,7 @@ module.exports = { console.log(response) sessionAttributes = response.sessionAttributes test.equal(response.message, "hook") - + response = await this.lex.postText({ sessionAttributes:sessionAttributes, inputText: "next" @@ -532,7 +532,7 @@ module.exports = { console.log(response) sessionAttributes = response.sessionAttributes test.equal(response.message, "Three") - + response = await this.lex.postText({ sessionAttributes:sessionAttributes, inputText: "previous" @@ -540,7 +540,7 @@ module.exports = { console.log(response) sessionAttributes = response.sessionAttributes test.equal(response.message, "hook") - + response = await this.lex.postText({ sessionAttributes:sessionAttributes, inputText: "previous" @@ -606,7 +606,7 @@ module.exports = { a: "One" } }) - + var sessionAttributes = {} var response response = await this.lex.postText({ @@ -616,7 +616,7 @@ module.exports = { console.log(response) sessionAttributes = response.sessionAttributes test.equal(response.message, "There is no question to leave feedback on, please ask a question before attempting to leave feedback") - + response = await this.lex.postText({ sessionAttributes:sessionAttributes, inputText: "One" @@ -624,7 +624,7 @@ module.exports = { console.log(response) sessionAttributes = response.sessionAttributes test.equal(response.message, "One") - + response = await this.lex.postText({ sessionAttributes:sessionAttributes, inputText: "feedback" @@ -632,7 +632,7 @@ module.exports = { console.log(response) sessionAttributes = response.sessionAttributes test.ok(response.message.includes("\"One\"")) - + response = await this.lex.postText({ sessionAttributes:sessionAttributes, inputText: "goodbye" @@ -640,7 +640,7 @@ module.exports = { console.log(response) sessionAttributes = response.sessionAttributes test.ok(response.message.includes("\"One\"")) - + response = await this.lex.postText({ sessionAttributes:sessionAttributes, inputText: "a" @@ -648,7 +648,7 @@ module.exports = { console.log(response) sessionAttributes = response.sessionAttributes test.ok(response.message.includes("Thank you for leaving the feedback")) - + response = await this.lex.postText({ sessionAttributes:sessionAttributes, inputText: "feedback" @@ -656,7 +656,7 @@ module.exports = { console.log(response) sessionAttributes = response.sessionAttributes test.ok(response.message.includes("\"One\"")) - + response = await this.lex.postText({ sessionAttributes:sessionAttributes, inputText: "C" @@ -664,7 +664,7 @@ module.exports = { console.log(response) sessionAttributes = response.sessionAttributes test.ok(response.message.includes("Canceled Feedback")) - + } catch (e) { test.ifError(e) diff --git a/templates/master/test/quiz.js b/templates/master/test/quiz.js index 8087ed5e6..0dd64d700 100644 --- a/templates/master/test/quiz.js +++ b/templates/master/test/quiz.js @@ -1,4 +1,4 @@ -var config = require('../../../config') +var config = require('../../../config.json') process.env.AWS_PROFILE = config.profile process.env.AWS_DEFAULT_REGION = config.region var query = require('query-string').stringify @@ -171,7 +171,7 @@ module.exports = { "Furniture used during the Lincoln administration.", "Engraved frames." ]; - + var matchIndex; for (var i = 1; i < splitArray.length; i++) { if (matchIndex === -1) { diff --git a/templates/master/test/routes.js b/templates/master/test/routes.js index 323f7b903..03e25fd44 100644 --- a/templates/master/test/routes.js +++ b/templates/master/test/routes.js @@ -1,4 +1,4 @@ -var config=require('../../../config') +var config=require('../../../config.json') process.env.AWS_PROFILE=config.profile process.env.AWS_DEFAULT_REGION=config.region var query=require('query-string').stringify @@ -33,7 +33,7 @@ module.exports={ .tap(test.ok) .tapCatch(()=>console.log("error",x.href)) .catch(test.ifError) - + })) }) .catch(test.ifError) @@ -57,7 +57,7 @@ module.exports={ }) .catch(test.ifError) .finally(()=>test.done()) - } + } }, health:{ get:test=>run({ @@ -113,7 +113,7 @@ module.exports={ path:"examples", method:"get" }) - + var documents=await api({ href:exampleHrefs._links.documents.href, method:"get" @@ -126,14 +126,14 @@ module.exports={ }) }) ) - test.done() + test.done() }, photos:async test=>{ var exampleHrefs=await api({ path:"examples", method:"get" }) - + var photos=await api({ href:exampleHrefs._links.photos.href, method:"get" @@ -149,7 +149,7 @@ module.exports={ }) }) ) - test.done() + test.done() } }, jobs:{ diff --git a/templates/master/test/services.js b/templates/master/test/services.js index 52b0e095f..ad73b6cbe 100644 --- a/templates/master/test/services.js +++ b/templates/master/test/services.js @@ -1,5 +1,5 @@ var _=require('lodash') -var config=require('../../../config') +var config=require('../../../config.json') var Promise=require('bluebird') var outputs=require('../../../bin/exports') var api=require('./util').api diff --git a/templates/master/test/util.js b/templates/master/test/util.js index fe16b3d2d..5613233b3 100644 --- a/templates/master/test/util.js +++ b/templates/master/test/util.js @@ -1,4 +1,4 @@ -var config=require('../../../config') +var config=require('../../../config.json') process.env.AWS_PROFILE=config.profile process.env.AWS_DEFAULT_REGION=config.region var query=require('query-string').stringify @@ -51,11 +51,11 @@ function api(opts){ } console.log("Request",JSON.stringify(request,null,2)) - var credentials=aws.config.credentials - var signed=sign(request,credentials) + var credentials=aws.config.credentials + var signed=sign(request,credentials) delete request.headers["Host"] - delete request.headers["Content-Length"] - + delete request.headers["Content-Length"] + return Promise.resolve(axios(signed)) .get('data') .tap(x=>console.log("response:",JSON.stringify(x,null,2))) diff --git a/templates/master/test/workflows/export.js b/templates/master/test/workflows/export.js index 0eaf837d7..1353a6f7f 100644 --- a/templates/master/test/workflows/export.js +++ b/templates/master/test/workflows/export.js @@ -1,4 +1,4 @@ -var config=require('../../../../config') +var config=require('../../../../config.json') process.env.AWS_PROFILE=config.profile process.env.AWS_DEFAULT_REGION=config.region var _=require('lodash') @@ -36,7 +36,7 @@ module.exports={ path:"jobs/imports", method:"GET" }) - .then(x=>x.jobs.map(y=>y.id).includes(name) ? + .then(x=>x.jobs.map(y=>y.id).includes(name) ? setTimeout(()=>next(--i),2000) : res(x) ) .catch(x=>x.statusCode===404, ()=>setTimeout(()=>next(--i),2000)) @@ -58,7 +58,7 @@ module.exports={ method:"GET" }) .tapCatch(console.log) - .then(x=>x.status==="InProgress" ? + .then(x=>x.status==="InProgress" ? setTimeout(()=>next(--i),2000) : res(x) ) .catch(x=>x.response.status===404, ()=>setTimeout(()=>next(--i),2000)) @@ -83,7 +83,7 @@ module.exports={ method:"PUT", body:{} }) - try{ + try{ var completed=await new Promise(async function(res,rej){ next(100) async function next(count){ @@ -122,7 +122,7 @@ module.exports={ href:`${info._links.exports.href}/test-all`, method:"DELETE", }) - test.done() + test.done() }, filter:async function(test){ var info=await api({ @@ -133,10 +133,10 @@ module.exports={ href:`${info._links.exports.href}/test-filter`, method:"PUT", body:{ - filter:"none.*" + filter:"none.*" } }) - try{ + try{ var completed=await new Promise(async function(res,rej){ next(100) async function next(count){ @@ -166,7 +166,7 @@ module.exports={ href:`${info._links.exports.href}/test-filter`, method:"DELETE", }) - test.done() + test.done() }, tearDown:async function(done){ await api({ diff --git a/templates/master/test/workflows/index.js b/templates/master/test/workflows/index.js index 242b3b190..9be5cf171 100644 --- a/templates/master/test/workflows/index.js +++ b/templates/master/test/workflows/index.js @@ -1,4 +1,4 @@ -var config=require('../../../../config') +var config=require('../../../../config.json') process.env.AWS_PROFILE=config.profile process.env.AWS_DEFAULT_REGION=config.region var query=require('query-string').stringify @@ -195,7 +195,7 @@ module.exports={ method:"GET" }) .tap(x=>console.log(JSON.stringify(x,null,2))) - .then(x=>x.jobs.map(y=>y.id).includes(name) ? + .then(x=>x.jobs.map(y=>y.id).includes(name) ? setTimeout(()=>next(--i),2000) : res(x) ) .catch(x=>x.statusCode===404, ()=>setTimeout(()=>next(--i),2000)) @@ -218,7 +218,7 @@ module.exports={ }) .tap(x=>console.log(JSON.stringify(x,null,2))) .tapCatch(console.log) - .then(x=>x.status==="InProgress" ? + .then(x=>x.status==="InProgress" ? setTimeout(()=>next(--i),2000) : res(x) ) .catch(x=>x.response.status===404, ()=>setTimeout(()=>next(--i),2000)) diff --git a/templates/master/tstallstack.js b/templates/master/tstallstack.js index 038764f78..c01ed680f 100644 --- a/templates/master/tstallstack.js +++ b/templates/master/tstallstack.js @@ -17,6 +17,7 @@ module.exports={ "VPCSubnetIdList" : { "Fn::Join" : [ ",", {"Ref":"VPCSubnetIdList"} ] }, "VPCSecurityGroupIdList": { "Fn::Join" : [ ",", {"Ref":"VPCSecurityGroupIdList"} ] }, "XraySetting":{"Ref": "XraySetting"}, + "AwsSdkLayerLambdaLayer":{"Ref":"AwsSdkLayerLambdaLayer"}, } } } diff --git a/templates/public-vpc-support/index.js b/templates/public-vpc-support/index.js index 308a695be..fdb0e6f03 100644 --- a/templates/public-vpc-support/index.js +++ b/templates/public-vpc-support/index.js @@ -7,32 +7,32 @@ var fs=Promise.promisifyAll(require('fs')) var _=require('lodash') var path=require('path') -var config=require('../../config') +var config=require('../../config.json') module.exports=Promise.resolve(require('../master')).then(function(base){ // customize description - base.Description = `(SO0189-vpc) QnABot with admin and client websites - (Version v${process.env.npm_package_version})`; + base.Description = `(SO0189-vpc) QnABot with admin and client websites - Version v${process.env.npm_package_version}`; base.Outputs=_.pick(base.Outputs,[ - "ContentDesignerURL", - "ClientURL", - "DashboardURL", - "UserPoolURL", - "LexV1BotName", - "LexV1BotAlias", - "LexV1Intent", - "LexV1IntentFallback", - "LexV2BotName", - "LexV2BotId", - "LexV2BotAlias", - "LexV2BotAliasId", - "LexV2Intent", - "LexV2IntentFallback", - "LexV2BotLocaleIds", - "FeedbackSNSTopic", - "ESProxyLambda", - "ElasticsearchEndpoint", - "ElasticsearchIndex", - "MetricsBucket" + 'ContentDesignerURL', + 'ClientURL', + 'DashboardURL', + 'UserPoolURL', + 'LexV1BotName', + 'LexV1BotAlias', + 'LexV1Intent', + 'LexV1IntentFallback', + 'LexV2BotName', + 'LexV2BotId', + 'LexV2BotAlias', + 'LexV2BotAliasId', + 'LexV2Intent', + 'LexV2IntentFallback', + 'LexV2BotLocaleIds', + 'FeedbackSNSTopic', + 'ESProxyLambda', + 'ElasticsearchEndpoint', + 'ElasticsearchIndex', + 'MetricsBucket' ]) base.Parameters=_.pick(base.Parameters,[ "Email", @@ -51,102 +51,115 @@ module.exports=Promise.resolve(require('../master')).then(function(base){ "VPCSecurityGroupIdList", "XraySetting", "EmbeddingsApi", - "EmbeddingsSagemakerEndpoint", "SagemakerInitialInstanceCount", "EmbeddingsLambdaArn", - "EmbeddingsLambdaDimensions" + "EmbeddingsLambdaDimensions", + 'LLMApi', + 'LLMSagemakerInstanceType', + 'LLMSagemakerInitialInstanceCount', + 'LLMLambdaArn' ]); base.Metadata = { - "AWS::CloudFormation::Interface": { - "ParameterGroups": [ + 'AWS::CloudFormation::Interface': { + 'ParameterGroups': [ { - "Label": { - "default": "Authentication" - }, - "Parameters": [ - "Email", - "Username", - "PublicOrPrivate" - ] + 'Label': { + 'default': 'Authentication' + }, + 'Parameters': [ + 'Email', + 'Username', + 'PublicOrPrivate' + ] }, { - "Label": { - "default": "VPC" - }, - "Parameters": [ - "VPCSubnetIdList", - "VPCSecurityGroupIdList" - ] + 'Label': { + 'default': 'VPC' + }, + 'Parameters': [ + 'VPCSubnetIdList', + 'VPCSecurityGroupIdList' + ] }, { - "Label": { - "default": "Amazon Kendra Integration" - }, - "Parameters": [ - "DefaultKendraIndexId" - ] + 'Label': { + 'default': 'Amazon Kendra Integration' + }, + 'Parameters': [ + 'DefaultKendraIndexId' + ] }, { - "Label": { - "default": "Amazon OpenSearch Service" - }, - "Parameters": [ - "ElasticSearchNodeCount", - "ElasticSearchEBSVolumeSize", - "Encryption", - "KibanaDashboardRetentionMinutes" - ] + 'Label': { + 'default': 'Amazon OpenSearch Service' + }, + 'Parameters': [ + 'ElasticSearchNodeCount', + 'ElasticSearchEBSVolumeSize', + 'Encryption', + 'KibanaDashboardRetentionMinutes' + ] }, { - "Label": { - "default": "Amazon LexV2" - }, - "Parameters": [ - "LexV2BotLocaleIds" - ] + 'Label': { + 'default': 'Amazon LexV2' + }, + 'Parameters': [ + 'LexV2BotLocaleIds' + ] + }, + { + 'Label': { + 'default': 'Semantic Search with Embeddings' + }, + 'Parameters': [ + 'EmbeddingsApi', + 'SagemakerInitialInstanceCount', + 'EmbeddingsLambdaArn', + 'EmbeddingsLambdaDimensions' + ] }, { - "Label": { - "default": "Semantic Search with Embeddings" + 'Label': { + 'default': 'LLM integration for contextual followup and generative answers' }, - "Parameters": [ - "EmbeddingsApi", - "EmbeddingsSagemakerEndpoint", - "EmbeddingsLambdaArn", - "EmbeddingsLambdaDimensions", - "SagemakerInitialInstanceCount" + 'Parameters': [ + 'LLMApi', + 'LLMSagemakerInstanceType', + 'LLMSagemakerInitialInstanceCount', + 'LLMLambdaArn' ] - }, - { - "Label": { - "default": "Miscellaneous" + }, + { + 'Label': { + 'default': 'Miscellaneous' }, - "Parameters": [ - "LexBotVersion", - "InstallLexResponseBots", - "FulfillmentConcurrency", - "XraySetting" + 'Parameters': [ + 'LexBotVersion', + 'InstallLexResponseBots', + 'FulfillmentConcurrency', + 'XraySetting' ] - } + } ] } }; - base.Conditions.Public={"Fn::Equals":[{"Ref":"PublicOrPrivate"},"PUBLIC"]} - base.Conditions.Encrypted={"Fn::Equals":[{"Ref":"Encryption"},"ENCRYPTED"]} - base.Conditions.AdminSignUp={"Fn::Equals":[true,true]} - base.Conditions.Domain={"Fn::Equals":[true,false]} - base.Conditions.BuildExamples={"Fn::Equals":[true,true]} - base.Conditions.CreateDomain={"Fn::Equals":[true,true]} - base.Conditions.DontCreateDomain={"Fn::Equals":[true,false]} - base.Conditions.VPCEnabled={ "Fn::Not": [ - { "Fn::Equals": [ "", - { "Fn::Join": [ "", { "Ref": "VPCSecurityGroupIdList" } ] } - ] } + base.Conditions.Public={'Fn::Equals':[{'Ref':'PublicOrPrivate'},'PUBLIC']} + base.Conditions.Encrypted={'Fn::Equals':[{'Ref':'Encryption'},'ENCRYPTED']} + base.Conditions.AdminSignUp={'Fn::Equals':[true,true]} + base.Conditions.Domain={'Fn::Equals':[true,false]} + base.Conditions.BuildExamples={'Fn::Equals':[true,true]} + base.Conditions.CreateDomain={'Fn::Equals':[true,true]} + base.Conditions.DontCreateDomain={'Fn::Equals':[true,false]} + base.Conditions.VPCEnabled={ 'Fn::Not': [ + { 'Fn::Equals': [ '', + { 'Fn::Join': [ '', { 'Ref': 'VPCSecurityGroupIdList' } ] } ] } - base.Conditions.EmbeddingsEnable= {"Fn::Not": [{ "Fn::Equals":[{"Ref":"EmbeddingsApi"},"DISABLED"]}]} - base.Conditions.EmbeddingsSagemaker = {"Fn::Equals":[{"Ref":"EmbeddingsApi"},"SAGEMAKER"]} - base.Conditions.EmbeddingsLambda = {"Fn::Equals":[{"Ref":"EmbeddingsApi"},"LAMBDA"]} - base.Conditions.EmbeddingsLambdaArn = {"Fn::Not": [{ "Fn::Equals":[{"Ref":"EmbeddingsLambdaArn"},""]}]} + ] } + base.Conditions.EmbeddingsEnable={'Fn::Not': [{ 'Fn::Equals':[{'Ref':'EmbeddingsApi'},'DISABLED']}]} + base.Conditions.EmbeddingsSagemaker={'Fn::Equals':[{'Ref':'EmbeddingsApi'},'SAGEMAKER']} + base.Conditions.EmbeddingsLambda={'Fn::Equals':[{'Ref':'EmbeddingsApi'},'LAMBDA']} + base.Conditions.EmbeddingsLambdaArn={'Fn::Not': [{ 'Fn::Equals':[{'Ref':'EmbeddingsLambdaArn'},'']}]} var out=JSON.stringify(base); @@ -184,9 +197,9 @@ module.exports=Promise.resolve(require('../master')).then(function(base){ // The next two replaces are order dependent. Keep in this order. out=out.replace( - /CommaDelimitedList/, "List") + /CommaDelimitedList/, 'List') out=out.replace( - /CommaDelimitedList/, "List") + /CommaDelimitedList/, 'List') return JSON.parse(out) }) diff --git a/templates/public/index.js b/templates/public/index.js index 87cf6a29f..c8486a8cd 100644 --- a/templates/public/index.js +++ b/templates/public/index.js @@ -3,136 +3,147 @@ // SPDX-License-Identifier: Apache-2.0 var Promise=require('bluebird') -var fs=Promise.promisifyAll(require('fs')) var _=require('lodash') -var path=require('path') -var config=require('../../config') +var config=require('../../config.json') module.exports=Promise.resolve(require('../master')).then(function(base){ // customize description - base.Description = `(SO0189) QnABot with admin and client websites - (Version v${process.env.npm_package_version})`; + base.Description = `(SO0189) QnABot with admin and client websites - Version v${process.env.npm_package_version}`; base.Outputs=_.pick(base.Outputs,[ - "ContentDesignerURL", - "ClientURL", - "DashboardURL", - "UserPoolURL", - "LexV1BotName", - "LexV1BotAlias", - "LexV1Intent", - "LexV1IntentFallback", - "LexV2BotName", - "LexV2BotId", - "LexV2BotAlias", - "LexV2BotAliasId", - "LexV2Intent", - "LexV2IntentFallback", - "LexV2BotLocaleIds", - "FeedbackSNSTopic", - "ESProxyLambda", - "ElasticsearchEndpoint", - "ElasticsearchIndex", - "MetricsBucket" + 'ContentDesignerURL', + 'ClientURL', + 'DashboardURL', + 'UserPoolURL', + 'LexV1BotName', + 'LexV1BotAlias', + 'LexV1Intent', + 'LexV1IntentFallback', + 'LexV2BotName', + 'LexV2BotId', + 'LexV2BotAlias', + 'LexV2BotAliasId', + 'LexV2Intent', + 'LexV2IntentFallback', + 'LexV2BotLocaleIds', + 'FeedbackSNSTopic', + 'ESProxyLambda', + 'ElasticsearchEndpoint', + 'ElasticsearchIndex', + 'MetricsBucket' ]) base.Parameters=_.pick(base.Parameters,[ - "Email", - "Username", - "DefaultKendraIndexId", - "Encryption", - "ElasticSearchNodeCount", - "ElasticSearchEBSVolumeSize", - "KibanaDashboardRetentionMinutes", - "PublicOrPrivate", - "LexV2BotLocaleIds", - "LexBotVersion", - "InstallLexResponseBots", - "FulfillmentConcurrency", - "XraySetting", - "EmbeddingsApi", - "EmbeddingsSagemakerEndpoint", - "SagemakerInitialInstanceCount", - "EmbeddingsLambdaArn", - "EmbeddingsLambdaDimensions" + 'Email', + 'Username', + 'DefaultKendraIndexId', + 'Encryption', + 'ElasticSearchNodeCount', + 'ElasticSearchEBSVolumeSize', + 'KibanaDashboardRetentionMinutes', + 'PublicOrPrivate', + 'LexV2BotLocaleIds', + 'LexBotVersion', + 'InstallLexResponseBots', + 'FulfillmentConcurrency', + 'XraySetting', + 'EmbeddingsApi', + 'SagemakerInitialInstanceCount', + 'EmbeddingsLambdaArn', + 'EmbeddingsLambdaDimensions', + 'LLMApi', + 'LLMSagemakerInstanceType', + 'LLMSagemakerInitialInstanceCount', + 'LLMLambdaArn' ]); base.Metadata = { - "AWS::CloudFormation::Interface": { - "ParameterGroups": [ + 'AWS::CloudFormation::Interface': { + 'ParameterGroups': [ { - "Label": { - "default": "Authentication" - }, - "Parameters": [ - "Email", - "Username", - "PublicOrPrivate" - ] + 'Label': { + 'default': 'Authentication' + }, + 'Parameters': [ + 'Email', + 'Username', + 'PublicOrPrivate' + ] }, { - "Label": { - "default": "Amazon Kendra Integration" - }, - "Parameters": [ - "DefaultKendraIndexId" - ] + 'Label': { + 'default': 'Amazon Kendra Integration' + }, + 'Parameters': [ + 'DefaultKendraIndexId' + ] + }, + { + 'Label': { + 'default': 'Amazon OpenSearch Service' + }, + 'Parameters': [ + 'ElasticSearchNodeCount', + 'ElasticSearchEBSVolumeSize', + 'Encryption', + 'KibanaDashboardRetentionMinutes' + ] }, { - "Label": { - "default": "Amazon OpenSearch Service" - }, - "Parameters": [ - "ElasticSearchNodeCount", - "ElasticSearchEBSVolumeSize", - "Encryption", - "KibanaDashboardRetentionMinutes" - ] + 'Label': { + 'default': 'Amazon LexV2' + }, + 'Parameters': [ + 'LexV2BotLocaleIds' + ] }, { - "Label": { - "default": "Amazon LexV2" - }, - "Parameters": [ - "LexV2BotLocaleIds" - ] + 'Label': { + 'default': 'Semantic Search with Embeddings' + }, + 'Parameters': [ + 'EmbeddingsApi', + 'SagemakerInitialInstanceCount', + 'EmbeddingsLambdaArn', + 'EmbeddingsLambdaDimensions' + ] }, { - "Label": { - "default": "Semantic Search with Embeddings" + 'Label': { + 'default': 'LLM integration for contextual followup and generative answers' }, - "Parameters": [ - "EmbeddingsApi", - "EmbeddingsSagemakerEndpoint", - "SagemakerInitialInstanceCount", - "EmbeddingsLambdaArn", - "EmbeddingsLambdaDimensions" + 'Parameters': [ + 'LLMApi', + 'LLMSagemakerInstanceType', + 'LLMSagemakerInitialInstanceCount', + 'LLMLambdaArn' ] - }, - { - "Label": { - "default": "Miscellaneous" + }, + { + 'Label': { + 'default': 'Miscellaneous' }, - "Parameters": [ - "LexBotVersion", - "InstallLexResponseBots", - "FulfillmentConcurrency", - "XraySetting" + 'Parameters': [ + 'LexBotVersion', + 'InstallLexResponseBots', + 'FulfillmentConcurrency', + 'XraySetting' ] - } + } ] } }; - base.Conditions.Public={"Fn::Equals":[{"Ref":"PublicOrPrivate"},"PUBLIC"]} - base.Conditions.Encrypted={"Fn::Equals":[{"Ref":"Encryption"},"ENCRYPTED"]} - base.Conditions.AdminSignUp={"Fn::Equals":[true,true]} - base.Conditions.Domain={"Fn::Equals":[true,false]} - base.Conditions.BuildExamples={"Fn::Equals":[true,true]} - base.Conditions.CreateDomain={"Fn::Equals":[true,true]} - base.Conditions.DontCreateDomain={"Fn::Equals":[true,false]} - base.Conditions.VPCEnabled={"Fn::Equals":[true,false]} - base.Conditions.SingleNode={"Fn::Equals":[{"Ref":"ElasticSearchNodeCount"},"1"]} - base.Conditions.EmbeddingsEnable= {"Fn::Not": [{ "Fn::Equals":[{"Ref":"EmbeddingsApi"},"DISABLED"]}]} - base.Conditions.EmbeddingsSagemaker = {"Fn::Equals":[{"Ref":"EmbeddingsApi"},"SAGEMAKER"]} - base.Conditions.EmbeddingsLambda = {"Fn::Equals":[{"Ref":"EmbeddingsApi"},"LAMBDA"]} - base.Conditions.EmbeddingsLambdaArn = {"Fn::Not": [{ "Fn::Equals":[{"Ref":"EmbeddingsLambdaArn"},""]}]} + base.Conditions.Public={'Fn::Equals':[{'Ref':'PublicOrPrivate'},'PUBLIC']} + base.Conditions.Encrypted={'Fn::Equals':[{'Ref':'Encryption'},'ENCRYPTED']} + base.Conditions.AdminSignUp={'Fn::Equals':[true,true]} + base.Conditions.Domain={'Fn::Equals':[true,false]} + base.Conditions.BuildExamples={'Fn::Equals':[true,true]} + base.Conditions.CreateDomain={'Fn::Equals':[true,true]} + base.Conditions.DontCreateDomain={'Fn::Equals':[true,false]} + base.Conditions.VPCEnabled={'Fn::Equals':[true,false]} + base.Conditions.SingleNode={'Fn::Equals':[{'Ref':'ElasticSearchNodeCount'},'1']} + base.Conditions.EmbeddingsEnable={'Fn::Not': [{ 'Fn::Equals':[{'Ref':'EmbeddingsApi'},'DISABLED']}]} + base.Conditions.EmbeddingsSagemaker={'Fn::Equals':[{'Ref':'EmbeddingsApi'},'SAGEMAKER']} + base.Conditions.EmbeddingsLambda={'Fn::Equals':[{'Ref':'EmbeddingsApi'},'LAMBDA']} + base.Conditions.EmbeddingsLambdaArn={'Fn::Not': [{ 'Fn::Equals':[{'Ref':'EmbeddingsLambdaArn'},'']}]} var out=JSON.stringify(base); diff --git a/templates/sagemaker-embeddings/index.js b/templates/sagemaker-embeddings/index.js index a7ebf9653..0dd5bac4f 100644 --- a/templates/sagemaker-embeddings/index.js +++ b/templates/sagemaker-embeddings/index.js @@ -2,7 +2,7 @@ const util = require('../util'); module.exports={ "AWSTemplateFormatVersion": "2010-09-09", - "Description": "(SO0189n-sagemaker) QnABot nested sagemaker embeddings resources", + "Description": `(SO0189n-sagemaker) QnABot nested sagemaker embeddings resources - Version v${process.env.npm_package_version}`, "Parameters": { "BootstrapBucket":{"Type":"String"}, "BootstrapPrefix":{"Type":"String"}, @@ -19,7 +19,7 @@ module.exports={ }, "Resources": { - "QnABotSMModelTarVersion": { + "QnABotModelTarVersion": { "Type": "Custom::S3Version", "Properties": { "ServiceToken": { "Ref": "CFNLambda" }, @@ -28,7 +28,7 @@ module.exports={ "BuildDate": (new Date()).toISOString() } }, - "QnABotSMEmbeddingModel": { + "QnABotEmbeddingModel": { "Type": "AWS::SageMaker::Model", "Properties": { "PrimaryContainer": { @@ -40,12 +40,12 @@ module.exports={ "Environment": { "SAGEMAKER_CONTAINER_LOG_LEVEL":"20", "SAGEMAKER_REGION":{"Ref":"AWS::Region"}, - "S3_MODEL_DATA_VERSION": {"Ref":"QnABotSMModelTarVersion"}, // force model replace when new version of tar file is available + "S3_MODEL_DATA_VERSION": {"Ref":"QnABotModelTarVersion"}, // force model replace when new version of tar file is available } }, "ExecutionRoleArn": { "Fn::GetAtt": [ - "QnABotSMEmbeddingModelExecutionRole", + "QnABotEmbeddingModelExecutionRole", "Arn" ] }, @@ -61,7 +61,7 @@ module.exports={ } } }, - "QnABotSMProvisionedEmbeddingEndpointConfig": { + "QnABotProvisionedEmbeddingEndpointConfig": { "Condition":"EmbeddingsSagemakerProvisioned", "Type": "AWS::SageMaker::EndpointConfig", "Properties": { @@ -69,7 +69,7 @@ module.exports={ { "ModelName": { "Fn::GetAtt": [ - "QnABotSMEmbeddingModel", + "QnABotEmbeddingModel", "ModelName" ] }, @@ -91,7 +91,7 @@ module.exports={ } } }, - "QnABotSMServerlessEmbeddingEndpointConfig": { + "QnABotServerlessEmbeddingEndpointConfig": { "Condition":"EmbeddingsSagemakerServerless", "Type": "AWS::SageMaker::EndpointConfig", "Properties": { @@ -99,7 +99,7 @@ module.exports={ { "ModelName": { "Fn::GetAtt": [ - "QnABotSMEmbeddingModel", + "QnABotEmbeddingModel", "ModelName" ] }, @@ -124,31 +124,31 @@ module.exports={ } }, - "QnABotSMProvisionedEmbeddingEndpoint": { + "QnABotProvisionedEmbeddingEndpoint": { "Condition":"EmbeddingsSagemakerProvisioned", "Type": "AWS::SageMaker::Endpoint", "Properties": { "EndpointConfigName": { "Fn::GetAtt": [ - "QnABotSMProvisionedEmbeddingEndpointConfig", + "QnABotProvisionedEmbeddingEndpointConfig", "EndpointConfigName" ] } } }, - "QnABotSMServerlessEmbeddingEndpoint": { + "QnABotServerlessEmbeddingEndpoint": { "Condition":"EmbeddingsSagemakerServerless", "Type": "AWS::SageMaker::Endpoint", "Properties": { "EndpointConfigName": { "Fn::GetAtt": [ - "QnABotSMServerlessEmbeddingEndpointConfig", + "QnABotServerlessEmbeddingEndpointConfig", "EndpointConfigName" ] } } }, - "QnABotSMEmbeddingModelExecutionRole": { + "QnABotEmbeddingModelExecutionRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -267,8 +267,8 @@ module.exports={ "Value": { "Fn::If": [ "EmbeddingsSagemakerProvisioned", - {"Fn::GetAtt":["QnABotSMProvisionedEmbeddingEndpoint","EndpointName"]}, - {"Fn::GetAtt":["QnABotSMServerlessEmbeddingEndpoint","EndpointName"]} + {"Fn::GetAtt":["QnABotProvisionedEmbeddingEndpoint","EndpointName"]}, + {"Fn::GetAtt":["QnABotServerlessEmbeddingEndpoint","EndpointName"]} ] } }, @@ -276,8 +276,8 @@ module.exports={ "Value":{ "Fn::If": [ "EmbeddingsSagemakerProvisioned", - {"Ref":"QnABotSMProvisionedEmbeddingEndpoint"}, - {"Ref":"QnABotSMServerlessEmbeddingEndpoint"} + {"Ref":"QnABotProvisionedEmbeddingEndpoint"}, + {"Ref":"QnABotServerlessEmbeddingEndpoint"} ] } } diff --git a/templates/sagemaker-qa-summarize-llm/Makefile b/templates/sagemaker-qa-summarize-llm/Makefile new file mode 100644 index 000000000..ce1990754 --- /dev/null +++ b/templates/sagemaker-qa-summarize-llm/Makefile @@ -0,0 +1,8 @@ +BUILD=../../bin/build.js +NAME=$(shell basename $(shell pwd)) +DST=../../build/templates/$(NAME).json + +default: sagemaker-qa-summarize-stack + +sagemaker-qa-summarize-stack: + $(BUILD) --stack $(NAME) --verbose diff --git a/templates/sagemaker-qa-summarize-llm/README.md b/templates/sagemaker-qa-summarize-llm/README.md new file mode 100644 index 000000000..8ef3aa1cb --- /dev/null +++ b/templates/sagemaker-qa-summarize-llm/README.md @@ -0,0 +1,2 @@ +# Create Sagemaker Endpoint +Nested stack for creating SM endpoint diff --git a/templates/sagemaker-qa-summarize-llm/index.js b/templates/sagemaker-qa-summarize-llm/index.js new file mode 100644 index 000000000..781803625 --- /dev/null +++ b/templates/sagemaker-qa-summarize-llm/index.js @@ -0,0 +1,272 @@ +const util = require('../util'); + +// Sagemaker Serverless Inference doesn't currently support the Falcon40B-Instruct model +// so although this nested template supports serverless provisioning, the main template enforces +// only provisioned endpoints by disallowing a value of '0' for SagemakerInitialInstanceCount + +module.exports={ + "AWSTemplateFormatVersion": "2010-09-09", + "Description": "(SO0189n-sagemaker) QnABot nested sagemaker QA summarization resources", + "Parameters": { + "BootstrapBucket":{"Type":"String"}, + "BootstrapPrefix":{"Type":"String"}, + "CFNLambda":{"Type":"String"}, + "SagemakerInstanceType":{"Type":"String"}, + "SagemakerInitialInstanceCount":{"Type":"Number"}, + "VPCSubnetIdList":{"Type": "String"}, + "VPCSecurityGroupIdList":{"Type": "String"}, + }, + + "Conditions": { + "SagemakerServerless":{"Fn::Equals":[{"Ref":"SagemakerInitialInstanceCount"},0]}, + "SagemakerProvisioned":{"Fn::Not":[{"Fn::Equals":[{"Ref":"SagemakerInitialInstanceCount"},0]}]}, + "VPCEnabled": {"Fn::Not":[{"Fn::Equals":["",{ "Ref": "VPCSecurityGroupIdList"}]}]}, + }, + + "Resources": { + "QnABotQASummarizeLLMModel": { + "Type": "AWS::SageMaker::Model", + "Properties": { + "PrimaryContainer": { + "Image": { + "Fn::Sub": "763104351884.dkr.ecr.${AWS::Region}.amazonaws.com/huggingface-pytorch-tgi-inference:2.0.0-tgi0.8.2-gpu-py39-cu118-ubuntu20.04" + }, + "Mode": "SingleModel", + "Environment": { + "SAGEMAKER_CONTAINER_LOG_LEVEL":"20", + "SAGEMAKER_REGION":{"Ref":"AWS::Region"}, + "HF_MODEL_ID": "tiiuae/falcon-40b-instruct", + "SM_NUM_GPUS":"4" + } + }, + "ExecutionRoleArn": { + "Fn::GetAtt": [ + "QnABotQASummarizeLLMModelExecutionRole", + "Arn" + ] + }, + "VpcConfig" : { + "Fn::If": [ + "VPCEnabled", + { + "Subnets": {"Fn::Split":[",",{"Ref":"VPCSubnetIdList"}]}, + "SecurityGroupIds":{"Fn::Split":[",",{"Ref":"VPCSecurityGroupIdList"}]}, + }, + {"Ref" : "AWS::NoValue"} + ] + } + } + }, + "QnABotProvisionedQASummarizeLLMEndpointConfig": { + "Condition":"SagemakerProvisioned", + "Type": "AWS::SageMaker::EndpointConfig", + "Properties": { + "ProductionVariants": [ + { + "ModelName": { + "Fn::GetAtt": [ + "QnABotQASummarizeLLMModel", + "ModelName" + ] + }, + "InitialInstanceCount": {"Ref":"SagemakerInitialInstanceCount"}, + "InitialVariantWeight": 1, + "InstanceType": {"Ref": "SagemakerInstanceType"}, + "VariantName": "AllTraffic", + } + ] + }, + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W1200", + "reason": "Default transient keys used by SageMaker for encryption is sufficient for use case" + } + ] + } + } + }, + "QnABotServerlessQASummarizeLLMEndpointConfig": { + "Condition":"SagemakerServerless", + "Type": "AWS::SageMaker::EndpointConfig", + "Properties": { + "ProductionVariants": [ + { + "ModelName": { + "Fn::GetAtt": [ + "QnABotQASummarizeLLMModel", + "ModelName" + ] + }, + "InitialVariantWeight": 1, + "VariantName": "AllTraffic", + "ServerlessConfig": { + "MaxConcurrency" : 50, + "MemorySizeInMB" : 4096 + } + } + ] + }, + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W1200", + "reason": "Default transient keys used by SageMaker for encryption is sufficient for use case" + } + ] + } + } + + }, + "QnABotProvisionedQASummarizeLLMEndpoint": { + "Condition":"SagemakerProvisioned", + "Type": "AWS::SageMaker::Endpoint", + "Properties": { + "EndpointConfigName": { + "Fn::GetAtt": [ + "QnABotProvisionedQASummarizeLLMEndpointConfig", + "EndpointConfigName" + ] + } + } + }, + "QnABotServerlessQASummarizeLLMEndpoint": { + "Condition":"SagemakerServerless", + "Type": "AWS::SageMaker::Endpoint", + "Properties": { + "EndpointConfigName": { + "Fn::GetAtt": [ + "QnABotServerlessQASummarizeLLMEndpointConfig", + "EndpointConfigName" + ] + } + } + }, + "QnABotQASummarizeLLMModelExecutionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "sagemaker.amazonaws.com" + ] + } + } + ] + }, + "Path": "/", + "Policies": [ + { + "PolicyName": "S3Policy", + "PolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "logs:CreateLogStream", + "logs:CreateLogGroup", + "logs:DescribeLogStreams", + ], + "Resource": [ + {"Fn::Sub":"arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/sagemaker/*"} + ] + }, + { + "Effect": "Allow", + "Action": [ + "logs:PutLogEvents", + ], + "Resource": [ + {"Fn::Sub":"arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/sagemaker/*:log-stream:*"} + ] + }, + { + "Effect": "Allow", + "Action": [ + "cloudwatch:PutMetricData", + "ecr:GetAuthorizationToken" + ], + "Resource": [ + // these actions cannot be bound to resources other than * + "*" + ] + }, + { + "Effect": "Allow", + "Action": [ + "ecr:BatchCheckLayerAvailability", + "ecr:GetDownloadUrlForLayer", + "ecr:BatchGetImage" + ], + "Resource": [ + {"Fn::Sub":"arn:${AWS::Partition}:ecr:${AWS::Region}:*:repository/huggingface-pytorch-tgi-inference"}, + ] + }, + + //ec2 permissions required for VPC access + { + "Action": [ + "ec2:DescribeVpcEndpoints", + "ec2:DescribeDhcpOptions", + "ec2:DescribeVpcs", + "ec2:DescribeSubnets", + "ec2:DescribeSecurityGroups", + "ec2:DescribeNetworkInterfaces" + ], + "Resource": [ + // these actions cannot be bound to resources other than * + "*" + ], + "Effect": "Allow" + }, + { + "Action": [ + "ec2:CreateNetworkInterface", + "ec2:CreateNetworkInterfacePermission" + ], + "Resource": [ + {"Fn::Sub":"arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:network-interface/*"}, + {"Fn::Sub":"arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:subnet/*"}, + {"Fn::Sub":"arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:security-group/*"} + ], + "Effect": "Allow" + } + ] + } + } + ] + }, + "Metadata": util.cfnNag(["W11"], "cloudwatch:PutMetricData, ecr:GetAuthorizationToken, and ec2:Describe* actions cannot be bound to a resource") + } + }, + "Outputs": { + "LLMSagemakerEndpoint": { + "Value": { + "Fn::If": [ + "SagemakerProvisioned", + {"Fn::GetAtt":["QnABotProvisionedQASummarizeLLMEndpoint","EndpointName"]}, + {"Fn::GetAtt":["QnABotServerlessQASummarizeLLMEndpoint","EndpointName"]} + ] + } + }, + "LLMSagemakerEndpointArn": { + "Value":{ + "Fn::If": [ + "SagemakerProvisioned", + {"Ref":"QnABotProvisionedQASummarizeLLMEndpoint"}, + {"Ref":"QnABotServerlessQASummarizeLLMEndpoint"} + ] + } + } + } +} \ No newline at end of file diff --git a/templates/testall/index.js b/templates/testall/index.js index 4d8a997a6..3f6490b14 100644 --- a/templates/testall/index.js +++ b/templates/testall/index.js @@ -9,7 +9,7 @@ module.exports={ "Resources":_.assign.apply({},files), "Conditions": {}, "AWSTemplateFormatVersion": "2010-09-09", - "Description": "(SO0189n-testall) QnABot nested testall resources", + "Description": `(SO0189n-testall) QnABot nested testall resources - Version v${process.env.npm_package_version}`, "Outputs": require('./outputs'), "Parameters": { "CFNLambda":{"Type":"String"}, @@ -24,7 +24,8 @@ module.exports={ "TestAllBucket": {"Type":"String"}, "VPCSubnetIdList" : {"Type": "String"}, "VPCSecurityGroupIdList": {"Type": "String"}, - "XraySetting": {"Type": "String"} + "XraySetting": {"Type": "String"}, + "AwsSdkLayerLambdaLayer":{"Type":"String"}, }, "Conditions": { "VPCEnabled": { "Fn::Not": [ diff --git a/templates/testall/resources.js b/templates/testall/resources.js index 391f3d144..a67443422 100644 --- a/templates/testall/resources.js +++ b/templates/testall/resources.js @@ -39,7 +39,7 @@ module.exports=Object.assign( "Handler": "index.step", "MemorySize": "1280", "Role": {"Fn::GetAtt": ["TestAllRole","Arn"]}, - "Runtime": "nodejs16.x", + "Runtime": process.env.npm_package_config_lambdaRuntime, "Timeout": 900, "VpcConfig" : { "Fn::If": [ "VPCEnabled", { @@ -51,6 +51,9 @@ module.exports=Object.assign( "Fn::If": [ "XRAYEnabled", {"Mode": "Active"}, {"Ref" : "AWS::NoValue"} ] }, + "Layers":[ + {"Ref":"AwsSdkLayerLambdaLayer"} + ], "Tags":[{ Key:"Type", Value:"TestAll" diff --git a/templates/util.js b/templates/util.js index fd4620000..5e991df1f 100644 --- a/templates/util.js +++ b/templates/util.js @@ -1,39 +1,3 @@ -exports.stack=function(name,parameters){ - return { - "Type" : "AWS::CloudFormation::Stack", - "Properties" : { - "TemplateURL" : {"Fn::Join":["/",[ - "https://s3.amazonaws.com", - {"Ref":"BootstrapBucket"}, - {"Ref":"BootstrapPrefix"}, - "templates/"+name+'.json' - ]]}, - "Parameters":Object.assign({ - "BootstrapBucket":{"Ref":"BootstrapBucket"}, - "BootstrapPrefix":{"Ref":"BootstrapPrefix"}, - },parameters) - } - } -} - -exports.stacktest=function(name,parameters){ - return { - "Type" : "AWS::CloudFormation::Stack", - "Properties" : { - "TemplateURL" : {"Fn::Join":["/",[ - "https://s3.amazonaws.com", - {"Fn::ImportValue":"QNA-BOOTSTRAP-BUCKET"}, - {"Fn::ImportValue":"QNA-BOOTSTRAP-PREFIX"}, - "templates/"+name+'.min.json' - ]]}, - "Parameters":Object.assign({ - "BootstrapBucket":{"Fn::ImportValue":"QNA-BOOTSTRAP-BUCKET"}, - "BootstrapPrefix":{"Fn::ImportValue":"QNA-BOOTSTRAP-PREFIX"} - },parameters) - } - } -} - exports.httpsOnlyBucketPolicy = function(bucketName = "Bucket") { return { "Type": "AWS::S3::BucketPolicy", diff --git a/website/config/dev.config.js b/website/config/dev.config.js index 17ec772f3..eecf74b59 100644 --- a/website/config/dev.config.js +++ b/website/config/dev.config.js @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -var config=require('../../config') +var config=require('../../config.json') var path=require('path') var S3Plugin = require('webpack-s3-plugin') diff --git a/website/config/test.config.js b/website/config/test.config.js index b91b8b7bc..19ffe8278 100644 --- a/website/config/test.config.js +++ b/website/config/test.config.js @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -var config=require('../../config') +var config=require('../../config.json') var path=require('path') var CopyWebpackPlugin = require('copy-webpack-plugin'); var HtmlWebpackPlugin = require('html-webpack-plugin'); @@ -49,9 +49,9 @@ module.exports={ } } }, - { - test: /\.(png|woff|woff2|eot|ttf|svg)$/, - loader: 'url-loader?limit=100000' + { + test: /\.(png|woff|woff2|eot|ttf|svg)$/, + loader: 'url-loader?limit=100000' }, { test: /\.pug$/, @@ -69,7 +69,7 @@ module.exports={ test: /\.scss$/, use: extractSass.extract({ use:[ - {loader: "css-loader" }, + {loader: "css-loader" }, {loader: "sass-loader" } ] }) diff --git a/website/config/webpack.config.js b/website/config/webpack.config.js index 904500963..8660de500 100644 --- a/website/config/webpack.config.js +++ b/website/config/webpack.config.js @@ -1,6 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -var config=require('../../config') +var config=require('../../config.json') process.env.AWS_PROFILE=config.profile process.env.AWS_DEFAULT_REGION=config.profile var Promise=require('bluebird') diff --git a/website/js/components/designer/menu-test.vue b/website/js/components/designer/menu-test.vue index a44fda674..5bd73170f 100644 --- a/website/js/components/designer/menu-test.vue +++ b/website/js/components/designer/menu-test.vue @@ -10,12 +10,11 @@ @keyup.enter="simulate" clearable ) - v-flex(xs5) - v-checkbox( - label="Score on answer field (instead of questions)" - v-model="score_answer" - true-value="true" - false-value="false" + v-flex(xs2) + v-select( + label="Match on:" + :items="['qna item questions', 'qna item answer', 'text item passage']" + v-model="score_on" ) v-layout(row) v-flex(xs5) @@ -56,7 +55,7 @@ module.exports={ query:"", topic:"", client_filter:"", - score_answer:"false" + score_on:"qna item questions" } }, components:{ @@ -68,7 +67,8 @@ module.exports={ query:this.query, topic:this.topic, client_filter:this.client_filter, - score_answer:this.score_answer + score_answer:this.score_answer, + score_on:this.score_on }) },500,{trailing:false,leading:true}) } diff --git a/website/js/lib/store/api/actions/index.js b/website/js/lib/store/api/actions/index.js index a8e10c266..96144b1de 100644 --- a/website/js/lib/store/api/actions/index.js +++ b/website/js/lib/store/api/actions/index.js @@ -199,7 +199,8 @@ module.exports=Object.assign( query:opts.query, topic:opts.topic || "", client_filter:opts.client_filter || "", - score_answer:opts.score_answer || "false", + score_answer: (opts.score_on === 'qna item answer') ? 'true' : 'false', + score_text_passage: (opts.score_on === 'text item passage') ? 'true' : 'false', from:opts.from || 0 }), method:'get',