Showing preview only (9,137K chars total). Download the full file or copy to clipboard to get everything.
Repository: aws-samples/aws-ai-qna-bot
Branch: main
Commit: 663cfb28fc7b
Files: 1077
Total size: 8.5 MB
Directory structure:
gitextract_l3hhubux/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── conditional_chaining.md
│ │ └── feature_request.md
│ └── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .nightswatch/
│ ├── functional/
│ │ ├── conftest.py
│ │ ├── files/
│ │ │ ├── EPCTerminology.csv
│ │ │ ├── import-fail-expected.json
│ │ │ ├── import-fail.xlsx
│ │ │ ├── import-pass-expected.json
│ │ │ ├── import-pass.xlsx
│ │ │ └── terms.csv
│ │ ├── helpers/
│ │ │ ├── __init__.py
│ │ │ ├── bot_intents/
│ │ │ │ ├── get_attribute.json
│ │ │ │ ├── greetings.json
│ │ │ │ └── set_attribute.json
│ │ │ ├── cfn_parameter_fetcher.py
│ │ │ ├── cloud_watch_client.py
│ │ │ ├── cognito_client.py
│ │ │ ├── iam_client.py
│ │ │ ├── kendra_client.py
│ │ │ ├── lex_client.py
│ │ │ ├── s3_client.py
│ │ │ ├── translate_client.py
│ │ │ ├── utils/
│ │ │ │ ├── __init__.py
│ │ │ │ └── textbox.py
│ │ │ └── website_model/
│ │ │ ├── __init__.py
│ │ │ ├── chat_page.py
│ │ │ ├── custom_terminology_page.py
│ │ │ ├── dom_operator.py
│ │ │ ├── edit_page.py
│ │ │ ├── export_page.py
│ │ │ ├── import_page.py
│ │ │ ├── kendra_page.py
│ │ │ ├── login_page.py
│ │ │ ├── menu_nav.py
│ │ │ └── settings_page.py
│ │ ├── pytest.ini
│ │ ├── question_bank/
│ │ │ ├── embeddings_questions.json
│ │ │ ├── guardrail_question.json
│ │ │ ├── import_questions.json
│ │ │ ├── import_questions_qna.json
│ │ │ ├── import_questions_slot.json
│ │ │ ├── import_questions_text.json
│ │ │ ├── kendra_questions.json
│ │ │ ├── large_import_questions.json
│ │ │ ├── llm_questions.json
│ │ │ ├── question_designer_questions.json
│ │ │ ├── routing_questions.json
│ │ │ ├── session_attribute_questions.json
│ │ │ ├── settings_questions.json
│ │ │ └── translate_questions.json
│ │ ├── test_1_login.py
│ │ ├── test_2_import.py
│ │ ├── test_embeddings.py
│ │ ├── test_export.py
│ │ ├── test_guardrails.py
│ │ ├── test_kendra.py
│ │ ├── test_knowledge_base.py
│ │ ├── test_lambda_hooks.py
│ │ ├── test_llm.py
│ │ ├── test_question_designer.py
│ │ ├── test_routing.py
│ │ ├── test_session_attribute.py
│ │ ├── test_settings.py
│ │ ├── test_translate.py
│ │ └── test_tuning.py
│ └── pyproject.toml
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.txt
├── NOTICE.txt
├── README.md
├── SECURITY.md
├── deployment/
│ ├── build-s3-dist.sh
│ └── run-unit-tests.sh
└── source/
├── .markdownlint.jsonc
├── .npmrc
├── .prettierignore
├── .prettierrc.yml
├── Makefile
├── assets/
│ ├── Makefile
│ ├── README.md
│ ├── default-utterances.json
│ └── examples/
│ ├── README.md
│ ├── documents/
│ │ ├── blog-samples-final.json
│ │ ├── blog-samples-final.txt
│ │ ├── blog-samples.json
│ │ └── blog-samples.txt
│ └── photos/
│ └── README.md
├── bin/
│ ├── .gitignore
│ ├── README.md
│ ├── URL.sh
│ ├── build.js
│ ├── check.js
│ ├── check_bucket_ownership.js
│ ├── config.js
│ ├── exports.js
│ ├── json.js
│ ├── launch.js
│ ├── license.js
│ ├── license.txt
│ ├── name.js
│ ├── update-public.sh
│ ├── upload.sh
│ └── wait.js
├── cli/
│ ├── .coveragerc
│ ├── README.md
│ ├── aws_solutions/
│ │ ├── core/
│ │ │ ├── __init__.py
│ │ │ ├── config.py
│ │ │ ├── helpers.py
│ │ │ └── logging.py
│ │ └── qnabot/
│ │ └── cli/
│ │ ├── __init__.py
│ │ ├── qnabot_cli.py
│ │ └── qnabot_cli_helper.py
│ ├── pyproject.toml
│ ├── pytest.ini
│ ├── run-pytest.py
│ └── tests/
│ ├── __init__.py
│ ├── aws_solutions/
│ │ ├── core/
│ │ │ ├── __init__.py
│ │ │ ├── test_helpers.py
│ │ │ ├── test_logging.py
│ │ │ └── test_solution_config.py
│ │ └── qnabot/
│ │ ├── __init__.py
│ │ ├── fixtures/
│ │ │ ├── cloudformation_fixtures.py
│ │ │ ├── qnabot-test-template.yaml
│ │ │ └── s3_fixtures.py
│ │ ├── test_qnabot_cli.py
│ │ └── test_qnabot_cli_helper.py
│ └── conftest.py
├── docs/
│ ├── Blogpost-BranchingNavigation.json
│ ├── Blogpost-SimpleNavigation.json
│ ├── Blogpost-SimpleNavigationSupporting.json
│ ├── LLM_Retrieval_and_generative_question_answering/
│ │ └── README.md
│ ├── PII_Detection_And_Redaction/
│ │ └── README.md
│ ├── Technical Information.md
│ ├── VPC_support/
│ │ └── README.md
│ ├── architecture.xml
│ ├── bedrock_guardrails/
│ │ └── README.md
│ ├── bedrock_knowledgebase_rag/
│ │ └── README.md
│ ├── bot_routing/
│ │ └── README.md
│ ├── client_filters.md
│ ├── connect_callback/
│ │ └── README.md
│ ├── custom_domain_name_setup/
│ │ └── README.md
│ ├── custom_terminology_guide/
│ │ ├── README.md
│ │ └── sample.csv
│ ├── excel_import/
│ │ ├── README.md
│ │ └── sample.xlsx
│ ├── handlebars/
│ │ └── README.md
│ ├── intent_slot_matching/
│ │ └── README.md
│ ├── kendra_crawler_guide/
│ │ └── README.md
│ ├── kendra_fallback/
│ │ └── README.md
│ ├── kendra_redirect/
│ │ └── README.md
│ ├── lambda_hooks/
│ │ ├── README.md
│ │ ├── lambda_hook_sdk.MD
│ │ └── q-business-lambda-hook-example/
│ │ ├── README.md
│ │ └── q-business-lambda-hook-template.yml
│ ├── llm_streaming_responses/
│ │ └── README.md
│ ├── multilanguage_support/
│ │ └── README.md
│ ├── overview/
│ │ └── README.md
│ ├── password_reset/
│ │ └── README.md
│ ├── qnabot_cli/
│ │ └── README.md
│ ├── recent_topics_lambda_hook_example/
│ │ ├── README.md
│ │ ├── recent topic settings.json
│ │ └── recent_topics_settings.json
│ ├── semantic_matching_using_LLM_embeddings/
│ │ └── README.md
│ ├── settings.md
│ ├── tuning_accuracy_guide/
│ │ └── README.md
│ ├── update_or_migrate_deployment/
│ │ └── README.md
│ ├── using_cloud9/
│ │ └── README.md
│ └── zombie.json
├── eslint.config.js
├── lambda/
│ ├── Makefile
│ ├── README.md
│ ├── aws-sdk-layer/
│ │ ├── Makefile
│ │ ├── package.json
│ │ └── sdk-config/
│ │ └── customSdkConfig.js
│ ├── cfn/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── lib/
│ │ │ ├── ApiDeployment.js
│ │ │ ├── CognitoDomain.js
│ │ │ ├── CognitoLogin.js
│ │ │ ├── CognitoRole.js
│ │ │ ├── CognitoUrl.js
│ │ │ ├── DefaultSettings.json
│ │ │ ├── ESCognitoClient.js
│ │ │ ├── LambdaVersion.js
│ │ │ ├── ModelAccess.js
│ │ │ ├── OpenSearchUpdates.js
│ │ │ ├── PostUpgradeImport.js
│ │ │ ├── PreUpgradeExport.js
│ │ │ ├── S3Lambda.js
│ │ │ ├── S3Unzip.js
│ │ │ ├── S3Version.js
│ │ │ ├── SettingsInitializer.js
│ │ │ ├── Variable.js
│ │ │ ├── base.js
│ │ │ ├── lex.js
│ │ │ └── util/
│ │ │ ├── customSdkConfig.js
│ │ │ ├── parseIntFromLexRequestObject.js
│ │ │ ├── promise.js
│ │ │ └── response.js
│ │ ├── package.json
│ │ └── test/
│ │ ├── index.fixtures.js
│ │ ├── index.test.js
│ │ └── lib/
│ │ ├── ApiDeployment.fixtures.js
│ │ ├── ApiDeployment.test.js
│ │ ├── CognitoDomain.fixtures.js
│ │ ├── CognitoDomain.test.js
│ │ ├── CognitoLogin.fixtures.js
│ │ ├── CognitoLogin.test.js
│ │ ├── CognitoRole.fixtures.js
│ │ ├── CognitoRole.test.js
│ │ ├── CognitoUrl.fixtures.js
│ │ ├── CognitoUrl.test.js
│ │ ├── ESCognitoClient.fixtures.js
│ │ ├── ESCognitoClient.test.js
│ │ ├── LambdaVersion.fixtures.js
│ │ ├── LambdaVersion.test.js
│ │ ├── ModelAccess.fixtures.js
│ │ ├── ModelAccess.test.js
│ │ ├── OpenSearchUpdates.fixtures.js
│ │ ├── OpenSearchUpdates.test.js
│ │ ├── PostUpgradeImport.fixtures.js
│ │ ├── PostUpgradeImport.test.js
│ │ ├── PreUpgradeExport.fixtures.js
│ │ ├── PreUpgradeExport.test.js
│ │ ├── S3Lambda.fixtures.js
│ │ ├── S3Lambda.test.js
│ │ ├── S3Unzip.fixtures.js
│ │ ├── S3Unzip.test.js
│ │ ├── S3Version.fixtures.js
│ │ ├── S3Version.test.js
│ │ ├── SettingsInitializer.fixtures.js
│ │ ├── SettingsInitializer.test.js
│ │ ├── Variable.fixtures.js
│ │ ├── Variable.test.js
│ │ ├── base.test.js
│ │ ├── lex.fixtures.js
│ │ ├── lex.test.js
│ │ └── util/
│ │ ├── customSdkConfig.test.js
│ │ ├── parseIntFromLexRequestObject.test.js
│ │ ├── promise.test.js
│ │ ├── response.fixtures.js
│ │ └── response.test.js
│ ├── cfn-lambda-layer/
│ │ ├── Makefile
│ │ └── package.json
│ ├── common-modules-layer/
│ │ ├── Makefile
│ │ ├── opensearch-client/
│ │ │ └── connection.js
│ │ └── package.json
│ ├── connect/
│ │ ├── Makefile
│ │ ├── flowsv2/
│ │ │ └── contactflowLexV2.json
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── package.json
│ │ ├── questions.json
│ │ └── test/
│ │ ├── contactflow.fixtures.js
│ │ └── index.test.js
│ ├── es-proxy-layer/
│ │ ├── Makefile
│ │ ├── jest.config.js
│ │ ├── lib/
│ │ │ ├── bedrock/
│ │ │ │ ├── AmazonEmbeddings.js
│ │ │ │ ├── AmazonNovaEmbeddings.js
│ │ │ │ ├── BedrockModelProviderPrototype.js
│ │ │ │ ├── CohereEmbeddings.js
│ │ │ │ ├── applyGuardrail.js
│ │ │ │ ├── bedrockAgents.js
│ │ │ │ ├── bedrockClient.js
│ │ │ │ ├── bedrockLLMProvider.js
│ │ │ │ ├── bedrockModelConstants.js
│ │ │ │ └── bedrockModels.js
│ │ │ ├── cfn.js
│ │ │ ├── cleanmetrics.js
│ │ │ ├── dialog-event/
│ │ │ │ ├── processDialogEvent.js
│ │ │ │ └── processSlots.js
│ │ │ ├── embeddings.js
│ │ │ ├── es-logging.js
│ │ │ ├── es_query.js
│ │ │ ├── esbodybuilder.js
│ │ │ ├── fulfillment-event/
│ │ │ │ ├── encryptor.js
│ │ │ │ ├── evaluateConditionalChaining.js
│ │ │ │ ├── getHit.js
│ │ │ │ ├── invokeLambda.js
│ │ │ │ ├── mergeNext.js
│ │ │ │ ├── processFulfillmentEvent.js
│ │ │ │ ├── qid.js
│ │ │ │ ├── runKendraQuery.js
│ │ │ │ ├── runLlmQa.js
│ │ │ │ ├── safeExpressionEvaluator.js
│ │ │ │ ├── updateResWithHit.js
│ │ │ │ └── utterance.js
│ │ │ ├── getConnectionId.js
│ │ │ ├── handlebars.js
│ │ │ ├── handler.js
│ │ │ ├── hits_topic_tiebreaker.js
│ │ │ ├── kendra.js
│ │ │ ├── kendraClient.js
│ │ │ ├── kendraQuery.js
│ │ │ ├── kendraRetrieve.js
│ │ │ ├── keywords.js
│ │ │ ├── llm.js
│ │ │ ├── qid.js
│ │ │ ├── query.js
│ │ │ ├── redactHelper.js
│ │ │ ├── request.js
│ │ │ ├── sanitizeOutput.js
│ │ │ ├── signS3URL.js
│ │ │ ├── supportedLanguages.js
│ │ │ ├── translate.js
│ │ │ ├── truncate.js
│ │ │ └── utterances.js
│ │ ├── package.json
│ │ └── test/
│ │ ├── applyGuardrail.test.js
│ │ ├── bedrockAgents.test.js
│ │ ├── bedrockModelConstants.test.js
│ │ ├── bedrockModels.test.js
│ │ ├── cfn.test.js
│ │ ├── dialog-event/
│ │ │ ├── processDialogEvent.fixtures.js
│ │ │ ├── processDialogEvent.test.js
│ │ │ ├── processSlots.fixtures.js
│ │ │ └── processSlots.test.js
│ │ ├── embeddings.test.js
│ │ ├── es-logging.test.js
│ │ ├── es_query.fixtures.js
│ │ ├── es_query.test.js
│ │ ├── fulfillment-event/
│ │ │ ├── evaluateConditionalChaining.test.js
│ │ │ ├── getHit.fixtures.js
│ │ │ ├── getHit.test.js
│ │ │ ├── mergeNext.test.js
│ │ │ ├── processFulfillmentEvent.fixtures.js
│ │ │ ├── processFulfillmentEvent.test.js
│ │ │ ├── runLlmQa.test.js
│ │ │ ├── safeExpressionEvaluator.test.js
│ │ │ ├── updateResWithHit.fixtures.js
│ │ │ └── updateResWithHit.test.js
│ │ ├── getConnectionId.test.js
│ │ ├── handlebars.fixtures.js
│ │ ├── handlebars.test.js
│ │ ├── kendra.fixtures.js
│ │ ├── kendra.test.js
│ │ ├── kendraQuery.fixtures.js
│ │ ├── kendraQuery.test.js
│ │ ├── kendraRetrieve.fixtures.js
│ │ ├── kendraRetrieve.test.js
│ │ ├── keywords.test.js
│ │ ├── llm.fixtures.js
│ │ ├── llm.test.js
│ │ ├── query.test.js
│ │ ├── redactHelper.test.js
│ │ ├── sanitizeOutput.test.js
│ │ ├── signS3Url.test.js
│ │ ├── translate.fixtures.js
│ │ └── translate.test.js
│ ├── export/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── createFAQ.js
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── kendraSync.js
│ │ ├── lib/
│ │ │ ├── clean.js
│ │ │ ├── join.js
│ │ │ ├── load.js
│ │ │ ├── start.js
│ │ │ └── step.js
│ │ ├── package.json
│ │ ├── parseJSON.js
│ │ └── test/
│ │ ├── createFAQ.test.js
│ │ ├── index.fixtures.js
│ │ ├── index.test.js
│ │ ├── kendraSync.test.js
│ │ ├── lib/
│ │ │ ├── clean.test.js
│ │ │ ├── join.test.js
│ │ │ ├── load.test.js
│ │ │ ├── start.test.js
│ │ │ └── step.test.js
│ │ ├── parseJSON.test.js
│ │ └── qna_FAQ.json
│ ├── fulfillment/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── lib/
│ │ │ ├── middleware/
│ │ │ │ ├── 1_parse.js
│ │ │ │ ├── 2_preprocess.js
│ │ │ │ ├── 3_query.js
│ │ │ │ ├── 4_hook.js
│ │ │ │ ├── 5_assemble.js
│ │ │ │ ├── 6_cache.js
│ │ │ │ ├── 7_userInfo.js
│ │ │ │ ├── README.md
│ │ │ │ ├── alexa.js
│ │ │ │ ├── jwt.js
│ │ │ │ ├── lex.js
│ │ │ │ ├── lexRouter.js
│ │ │ │ ├── multilanguage.js
│ │ │ │ ├── sentiment.js
│ │ │ │ ├── specialtyBotRouter.js
│ │ │ │ └── util.js
│ │ │ └── router/
│ │ │ ├── README.md
│ │ │ └── index.js
│ │ ├── package.json
│ │ └── test/
│ │ ├── alexa/
│ │ │ ├── README.md
│ │ │ ├── cancel.json
│ │ │ ├── end.json
│ │ │ ├── intent.json
│ │ │ ├── schema.json
│ │ │ └── start.json
│ │ ├── index.fixtures.js
│ │ ├── index.test.js
│ │ ├── lex/
│ │ │ ├── README.md
│ │ │ ├── index.js
│ │ │ └── schema.json
│ │ └── lib/
│ │ └── middleware/
│ │ ├── 1_parse.fixtures.js
│ │ ├── 1_parse.test.js
│ │ ├── 2_preprocess.fixtures.js
│ │ ├── 2_preprocess.test.js
│ │ ├── 3_query.fixtures.js
│ │ ├── 3_query.test.js
│ │ ├── 4_hook.test.js
│ │ ├── 5_assemble.fixtures.js
│ │ ├── 5_assemble.test.js
│ │ ├── 6_cache.test.js
│ │ ├── 7_userInfo.test.js
│ │ ├── __mocks__/
│ │ │ └── esQueryMock.js
│ │ ├── alexa.fixtures.js
│ │ ├── alexa.test.js
│ │ ├── jwt.fixtures.js
│ │ ├── jwt.test.js
│ │ ├── lex.fixtures.js
│ │ ├── lex.test.js
│ │ ├── lexRouter.fixtures.js
│ │ ├── lexRouter.test.js
│ │ ├── multilanguage.fixtures.js
│ │ ├── multilanguage.test.js
│ │ ├── sentiment.test.js
│ │ ├── specialtyBotRouter.fixtures.js
│ │ ├── specialtyBotRouter.test.js
│ │ ├── util.fixtures.js
│ │ └── util.test.js
│ ├── genesys/
│ │ ├── Makefile
│ │ ├── flowsv2/
│ │ │ └── QnABot-CallFlow.yaml
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── package.json
│ │ └── test/
│ │ ├── callflow.fixtures.yaml
│ │ └── index.test.js
│ ├── import/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── convert-xlsx.js
│ │ ├── delete_existing_content.js
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── package.json
│ │ └── test/
│ │ ├── convert-xlsx.test.js
│ │ ├── delete_existing_content.test.js
│ │ ├── import-test.xlsx
│ │ ├── index.test.js
│ │ └── lib/
│ │ └── __mocks__/
│ │ ├── embeddingsMock.js
│ │ └── requestMock.js
│ ├── js_lambda_hook_sdk/
│ │ ├── Makefile
│ │ ├── jest.config.js
│ │ ├── lambda_hook_sdk/
│ │ │ └── hooks.js
│ │ ├── package.json
│ │ └── test/
│ │ ├── hooks.fixtures.js
│ │ └── hooks.test.js
│ ├── kendra-webcrawler/
│ │ ├── .coveragerc
│ │ ├── Makefile
│ │ ├── kendra-dashboard.json
│ │ ├── kendra_webcrawler.py
│ │ ├── pyproject.toml
│ │ ├── pytest.ini
│ │ ├── role.txt
│ │ └── test/
│ │ ├── conftest.py
│ │ └── test_lambda_function.py
│ ├── kendra-webcrawler-schedule-updater/
│ │ ├── .coveragerc
│ │ ├── Makefile
│ │ ├── kendra_webcrawler_schedule_updater.py
│ │ ├── pyproject.toml
│ │ ├── pytest.ini
│ │ └── test/
│ │ ├── conftest.py
│ │ └── test_lambda_function.py
│ ├── kendra-webcrawler-status/
│ │ ├── .coveragerc
│ │ ├── Makefile
│ │ ├── kendra_webcrawler_status.py
│ │ ├── pyproject.toml
│ │ ├── pytest.ini
│ │ ├── role.txt
│ │ └── test/
│ │ ├── conftest.py
│ │ └── test_lambda_function.py
│ ├── lex-build/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── lib/
│ │ │ ├── README.md
│ │ │ ├── index.js
│ │ │ ├── lexv2bot.js
│ │ │ ├── qidsandquestions.js
│ │ │ └── statusv2.js
│ │ ├── package.json
│ │ └── test/
│ │ └── lib/
│ │ ├── __mocks__/
│ │ │ └── conMock.js
│ │ ├── es.fixtures.js
│ │ ├── index.test.js
│ │ ├── intent.fixtures.js
│ │ ├── lexv2bot.test.js
│ │ ├── qidsandquestions.test.js
│ │ └── statusv2.test.js
│ ├── lexv2-build/
│ │ ├── .coveragerc
│ │ ├── Makefile
│ │ ├── handler.py
│ │ ├── pyproject.toml
│ │ ├── pytest.ini
│ │ └── test/
│ │ ├── conftest.py
│ │ └── test_lambda_function.py
│ ├── proxy-es/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── resource.js
│ ├── q-business-lambda-hook/
│ │ ├── Makefile
│ │ └── q_business_lambda_hook.py
│ ├── qnabot-common-layer/
│ │ ├── Makefile
│ │ ├── jest.config.js
│ │ ├── package.json
│ │ ├── qnabot/
│ │ │ ├── logging.js
│ │ │ └── settings.js
│ │ └── test/
│ │ ├── logging.fixtures.js
│ │ ├── logging.test.js
│ │ ├── settings.fixtures.js
│ │ └── settings.test.js
│ ├── s3-clean/
│ │ ├── .coveragerc
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── lambda_function.py
│ │ ├── pyproject.toml
│ │ ├── pytest.ini
│ │ └── test/
│ │ ├── conftest.py
│ │ └── test_lambda_function.py
│ ├── schema/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── package.json
│ │ ├── qna.js
│ │ ├── quiz.js
│ │ ├── slottype.js
│ │ ├── test/
│ │ │ └── index.test.js
│ │ └── text.js
│ ├── solution-helper/
│ │ ├── .coveragerc
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── lambda_function.py
│ │ ├── pyproject.toml
│ │ ├── pytest.ini
│ │ └── test/
│ │ ├── conftest.py
│ │ └── test_lambda_function.py
│ ├── streaming/
│ │ ├── Makefile
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test/
│ │ └── index.test.js
│ ├── test.js
│ ├── testall/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── lib/
│ │ │ ├── clean.js
│ │ │ ├── lex.js
│ │ │ ├── load.js
│ │ │ ├── start.js
│ │ │ └── step.js
│ │ ├── package.json
│ │ └── test/
│ │ ├── index.fixtures.js
│ │ ├── index.test.js
│ │ └── lib/
│ │ ├── clean.test.js
│ │ ├── lex.fixtures.js
│ │ ├── lex.test.js
│ │ ├── load.test.js
│ │ ├── start.test.js
│ │ └── step.test.js
│ ├── translate/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── package.json
│ │ └── test/
│ │ ├── index.test.js
│ │ └── translate.fixtures.js
│ └── warmer/
│ ├── Makefile
│ ├── index.js
│ ├── jest.config.js
│ ├── lib/
│ │ └── index.js
│ ├── package.json
│ └── test/
│ ├── index.test.js
│ └── lib/
│ └── index.test.js
├── package.json
├── templates/
│ ├── .gitignore
│ ├── README.md
│ ├── __mocks__/
│ │ └── @smithy/
│ │ └── uuid.js
│ ├── __tests__/
│ │ └── setup.js
│ ├── dev/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── __tests__/
│ │ │ ├── __snapshots__/
│ │ │ │ ├── bucket.test.js.snap
│ │ │ │ └── dev.test.js.snap
│ │ │ ├── bucket.test.js
│ │ │ ├── dev.test.js
│ │ │ ├── masterConfig.test.js
│ │ │ ├── masterNoConfig.test.js
│ │ │ ├── mockConfigEmpty.json
│ │ │ ├── mockConfigFull.json
│ │ │ └── mockMaster.js
│ │ ├── api.js
│ │ ├── bootstrap/
│ │ │ ├── README.md
│ │ │ ├── __snapshots__/
│ │ │ │ └── index.test.js.snap
│ │ │ ├── __tests__/
│ │ │ │ ├── handler.fixtures.js
│ │ │ │ └── handler.test.js
│ │ │ ├── handler.js
│ │ │ ├── index.js
│ │ │ └── index.test.js
│ │ ├── bucket.js
│ │ ├── cognito.js
│ │ ├── lambda.js
│ │ └── master.js
│ ├── examples/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── __snapshots__/
│ │ │ └── index.test.js.snap
│ │ ├── examples/
│ │ │ ├── Makefile
│ │ │ ├── README.md
│ │ │ ├── __tests__/
│ │ │ │ └── cfn.test.js
│ │ │ ├── cfn.js
│ │ │ ├── examples/
│ │ │ │ ├── ClientFilterDemo.json
│ │ │ │ ├── ClientFilterDemo.txt
│ │ │ │ ├── ConditionalChainingDemo.json
│ │ │ │ ├── ConditionalChainingDemo.txt
│ │ │ │ ├── ConnectCallback.json
│ │ │ │ ├── ConnectCallback.txt
│ │ │ │ ├── ConnectWizardQnA.json
│ │ │ │ ├── ConnectWizardQnA.txt
│ │ │ │ ├── Embeddings.json
│ │ │ │ ├── Embeddings.txt
│ │ │ │ ├── GenesysWizardQnA.json
│ │ │ │ ├── GenesysWizardQnA.txt
│ │ │ │ ├── GreetingHook.json
│ │ │ │ ├── GreetingHook.txt
│ │ │ │ ├── PrairieLineTrailTour.json
│ │ │ │ ├── PrairieLineTrailTour.txt
│ │ │ │ ├── QnaUtility.json
│ │ │ │ ├── QnaUtility.txt
│ │ │ │ ├── RecentTopicsDemo.json
│ │ │ │ ├── RecentTopicsDemo.txt
│ │ │ │ ├── TextPassage-NurseryRhymeExamples.json
│ │ │ │ ├── TextPassage-NurseryRhymeExamples.txt
│ │ │ │ ├── guided-navigation.json
│ │ │ │ ├── guided-navigation.txt
│ │ │ │ ├── markdownSSML.json
│ │ │ │ ├── markdownSSML.txt
│ │ │ │ ├── quiz.json
│ │ │ │ ├── quiz.txt
│ │ │ │ ├── repromptDemo.json
│ │ │ │ ├── repromptDemo.txt
│ │ │ │ ├── topic.json
│ │ │ │ └── topic.txt
│ │ │ ├── index.js
│ │ │ ├── js/
│ │ │ │ ├── Quiz.js
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── Quiz.fixtures.js
│ │ │ │ │ ├── Quiz.test.js
│ │ │ │ │ └── hook.test.js
│ │ │ │ ├── hook.js
│ │ │ │ └── templates/
│ │ │ │ ├── quiz-response.hbs
│ │ │ │ └── quiz-response.md
│ │ │ ├── package.json
│ │ │ ├── py/
│ │ │ │ ├── BotBroker.py
│ │ │ │ ├── ConnectCallback.py
│ │ │ │ ├── Feedback.py
│ │ │ │ ├── Next.py
│ │ │ │ ├── Previous.py
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── conftest.py
│ │ │ │ │ ├── test_ConnectCallback.py
│ │ │ │ │ ├── test_Feedback.py
│ │ │ │ │ ├── test_Next.py
│ │ │ │ │ ├── test_Previous.py
│ │ │ │ │ └── test_hello.py
│ │ │ │ ├── hello.py
│ │ │ │ ├── pyproject.toml
│ │ │ │ └── pytest.ini
│ │ │ └── responsebots-lexv2.js
│ │ ├── extensions/
│ │ │ ├── Makefile
│ │ │ ├── README.md
│ │ │ ├── index.js
│ │ │ ├── js_lambda_hooks/
│ │ │ │ ├── CreateRecentTopicsResponse/
│ │ │ │ │ ├── CreateRecentTopicsResponse.js
│ │ │ │ │ └── package.json
│ │ │ │ └── CustomJSHook/
│ │ │ │ ├── CustomJSHook.js
│ │ │ │ ├── __tests__/
│ │ │ │ │ └── CustomJSHook.test.js
│ │ │ │ └── package.json
│ │ │ ├── py_lambda_hooks/
│ │ │ │ └── CustomPYHook/
│ │ │ │ ├── CustomPYHook.py
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── conftest.py
│ │ │ │ │ └── test_CustomPYHook.py
│ │ │ │ ├── pyproject.toml
│ │ │ │ └── pytest.ini
│ │ │ └── ui_imports/
│ │ │ ├── content/
│ │ │ │ ├── CustomHook.json
│ │ │ │ ├── CustomHook.txt
│ │ │ │ ├── IntentSlotMatching.json
│ │ │ │ ├── IntentSlotMatching.txt
│ │ │ │ ├── Language.json
│ │ │ │ └── Language.txt
│ │ │ ├── package.json
│ │ │ └── ui_import.js
│ │ ├── index.js
│ │ ├── index.test.js
│ │ └── outputs.js
│ ├── export/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── __snapshots__/
│ │ │ └── index.test.js.snap
│ │ ├── bucket.js
│ │ ├── index.js
│ │ ├── index.test.js
│ │ ├── outputs.js
│ │ └── resources.js
│ ├── import/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── UpgradeAutoImport.js
│ │ ├── __snapshots__/
│ │ │ └── index.test.js.snap
│ │ ├── bucket.js
│ │ ├── index.js
│ │ ├── index.test.js
│ │ ├── outputs.js
│ │ └── resources.js
│ ├── jest.config.js
│ ├── master/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── UpgradeAutoExport.js
│ │ ├── __snapshots__/
│ │ │ └── index.test.js.snap
│ │ ├── assets.js
│ │ ├── bucket.js
│ │ ├── cfn/
│ │ │ ├── __tests__/
│ │ │ │ ├── handler.fixtures.js
│ │ │ │ └── handler.test.js
│ │ │ ├── handler.js
│ │ │ └── index.js
│ │ ├── cognito/
│ │ │ ├── index.js
│ │ │ ├── invite.txt
│ │ │ └── style/
│ │ │ ├── README.md
│ │ │ ├── client.scss
│ │ │ ├── cognito-login.css
│ │ │ ├── designer.scss
│ │ │ ├── index.html
│ │ │ └── index.js
│ │ ├── config.js
│ │ ├── dashboard/
│ │ │ ├── README.md
│ │ │ ├── body.js
│ │ │ ├── index.js
│ │ │ ├── lambdas.js
│ │ │ ├── opensearch.js
│ │ │ └── util.js
│ │ ├── dynamodb/
│ │ │ └── index.js
│ │ ├── examples.js
│ │ ├── exportstack.js
│ │ ├── importstack.js
│ │ ├── index.js
│ │ ├── index.test.js
│ │ ├── lambda-layers.js
│ │ ├── lambda.js
│ │ ├── lex/
│ │ │ ├── README.md
│ │ │ ├── bot.js
│ │ │ ├── config.js
│ │ │ ├── fulfillment.js
│ │ │ └── index.js
│ │ ├── lex-build/
│ │ │ ├── __tests__/
│ │ │ │ ├── poll.test.js
│ │ │ │ ├── start.test.js
│ │ │ │ └── test.json
│ │ │ ├── index.js
│ │ │ ├── poll.js
│ │ │ └── start.js
│ │ ├── lexv2-build/
│ │ │ └── index.js
│ │ ├── mappings/
│ │ │ ├── anonymized-data.js
│ │ │ └── bedrock-defaults.js
│ │ ├── opensearch/
│ │ │ ├── README.md
│ │ │ ├── __tests__/
│ │ │ │ ├── handler.fixtures.js
│ │ │ │ └── handler.test.js
│ │ │ ├── es.js
│ │ │ ├── firehose.js
│ │ │ ├── handler.js
│ │ │ ├── index.js
│ │ │ ├── index_mappings.js
│ │ │ ├── index_settings.js
│ │ │ ├── info.js
│ │ │ ├── opensearch-dashboards/
│ │ │ │ ├── QnABotDashboard.json
│ │ │ │ └── README.md
│ │ │ ├── proxy.js
│ │ │ └── updates.js
│ │ ├── policies.json
│ │ ├── proxy-es.js
│ │ ├── proxy-lex/
│ │ │ ├── README.md
│ │ │ ├── handler.js
│ │ │ ├── index.js
│ │ │ ├── status.js
│ │ │ └── test.js
│ │ ├── roles.json
│ │ ├── routes/
│ │ │ ├── README.md
│ │ │ ├── bot/
│ │ │ │ ├── alexa.vm
│ │ │ │ ├── get.resp.vm
│ │ │ │ ├── get.vm
│ │ │ │ ├── index.js
│ │ │ │ ├── post.resp.vm
│ │ │ │ ├── post.vm
│ │ │ │ ├── test.js
│ │ │ │ └── utterance.get.vm
│ │ │ ├── error/
│ │ │ │ ├── error.vm
│ │ │ │ └── test.js
│ │ │ ├── examples/
│ │ │ │ ├── handler.js
│ │ │ │ ├── index.js
│ │ │ │ ├── info.vm
│ │ │ │ ├── list.vm
│ │ │ │ ├── photos.vm
│ │ │ │ └── test.js
│ │ │ ├── health/
│ │ │ │ ├── health.resp.vm
│ │ │ │ ├── health.vm
│ │ │ │ ├── index.js
│ │ │ │ └── test.js
│ │ │ ├── images.js
│ │ │ ├── index.js
│ │ │ ├── jobs/
│ │ │ │ ├── __tests__/
│ │ │ │ │ └── handler.test.js
│ │ │ │ ├── export-start.vm
│ │ │ │ ├── handler.js
│ │ │ │ ├── index.js
│ │ │ │ ├── info.vm
│ │ │ │ ├── list-export.vm
│ │ │ │ ├── list-testall.vm
│ │ │ │ ├── list.vm
│ │ │ │ ├── test.js
│ │ │ │ └── testall-start.vm
│ │ │ ├── login.js
│ │ │ ├── proxy.js
│ │ │ ├── qa/
│ │ │ │ ├── collection/
│ │ │ │ │ ├── delete.resp.vm
│ │ │ │ │ └── delete.vm
│ │ │ │ ├── index.js
│ │ │ │ ├── single/
│ │ │ │ │ ├── delete.resp.vm
│ │ │ │ │ ├── delete.vm
│ │ │ │ │ ├── get.resp.vm
│ │ │ │ │ ├── get.vm
│ │ │ │ │ ├── head.resp.vm
│ │ │ │ │ ├── head.vm
│ │ │ │ │ ├── options.vm
│ │ │ │ │ ├── put.resp.vm
│ │ │ │ │ └── put.vm
│ │ │ │ └── test.js
│ │ │ ├── root/
│ │ │ │ ├── index.js
│ │ │ │ ├── info.vm
│ │ │ │ └── test.js
│ │ │ ├── services/
│ │ │ │ ├── index.js
│ │ │ │ ├── info.vm
│ │ │ │ └── test.js
│ │ │ ├── test.js
│ │ │ └── util/
│ │ │ ├── context.js
│ │ │ ├── lambda.js
│ │ │ ├── mock.js
│ │ │ ├── options.js
│ │ │ ├── redirect.js
│ │ │ ├── resource.js
│ │ │ └── temp-test.js
│ │ ├── s3-clean/
│ │ │ └── index.js
│ │ ├── s3.js
│ │ ├── schemaLambda.js
│ │ ├── settings.js
│ │ ├── signup/
│ │ │ ├── README.md
│ │ │ ├── __tests__/
│ │ │ │ ├── message.fixtures.js
│ │ │ │ ├── message.test.js
│ │ │ │ ├── signup.fixtures.js
│ │ │ │ └── signup.test.js
│ │ │ ├── index.js
│ │ │ ├── message.js
│ │ │ └── signup.js
│ │ ├── solution-helper/
│ │ │ └── index.js
│ │ ├── streamingstack.js
│ │ ├── tstallstack.js
│ │ └── var.js
│ ├── package.json
│ ├── public/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── __tests__/
│ │ │ ├── expectedResult.js
│ │ │ ├── indexConfig.test.js
│ │ │ ├── indexNoConfig.test.js
│ │ │ ├── mockConfig.json
│ │ │ └── mockMaster.js
│ │ └── index.js
│ ├── public-vpc-support/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── __tests__/
│ │ │ ├── expectedResult.js
│ │ │ ├── indexConfig.test.js
│ │ │ ├── indexNoConfig.test.js
│ │ │ ├── mockConfig.json
│ │ │ └── mockMaster.js
│ │ └── index.js
│ ├── streaming/
│ │ ├── Makefile
│ │ ├── index.js
│ │ ├── outputs.js
│ │ └── resources.js
│ ├── testall/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── __snapshots__/
│ │ │ └── index.test.js.snap
│ │ ├── bucket.js
│ │ ├── index.js
│ │ ├── index.test.js
│ │ ├── outputs.js
│ │ └── resources.js
│ └── util.js
├── utility_scripts/
│ ├── README.md
│ ├── configureAlerts.py
│ ├── configureCMK.py
│ ├── count_user_interactions.js
│ ├── create_kendra_faq_resources.js
│ ├── csv2json_converter/
│ │ ├── CSV2JSON_README.md
│ │ ├── css/
│ │ │ └── qnabot_csv2json_converter.css
│ │ ├── js/
│ │ │ ├── csvToArray.v2.1.js
│ │ │ └── qnabot_csv2json_converter.js
│ │ ├── qnabot_csv2json_converter.html
│ │ └── sample.csv
│ ├── migration.md
│ └── validate-conditional-chaining.js
└── website/
├── .babelrc
├── .gitignore
├── Makefile
├── README.md
├── __tests__/
│ ├── admin.spec.js
│ ├── admin.test.js
│ ├── client.spec.js
│ ├── client.test.js
│ ├── components/
│ │ ├── alexa/
│ │ │ └── index.spec.js
│ │ ├── connect/
│ │ │ └── index.spec.js
│ │ ├── customTranslate.spec.js
│ │ ├── designer/
│ │ │ ├── add.spec.js
│ │ │ ├── addSetting.spec.js
│ │ │ ├── alexa.spec.js
│ │ │ ├── delete.spec.js
│ │ │ ├── display.spec.js
│ │ │ ├── edit.spec.js
│ │ │ ├── empty.test.js
│ │ │ ├── event-bus.test.js
│ │ │ ├── index.spec.js
│ │ │ ├── input.spec.js
│ │ │ ├── menu-questions.spec.js
│ │ │ ├── menu-test.spec.js
│ │ │ ├── qa.spec.js
│ │ │ ├── rebuild.spec.js
│ │ │ └── synckendra.spec.js
│ │ ├── export.spec.js
│ │ ├── genesys/
│ │ │ └── index.spec.js
│ │ ├── hooks/
│ │ │ └── index.spec.js
│ │ ├── import.spec.js
│ │ ├── kendraIndex.spec.js
│ │ └── settings.spec.js
│ ├── lib/
│ │ ├── client-auth.test.js
│ │ ├── index.test.js
│ │ ├── router.test.js
│ │ └── store/
│ │ ├── api/
│ │ │ └── actions/
│ │ │ ├── connect.test.js
│ │ │ ├── export.test.js
│ │ │ ├── genesys.test.js
│ │ │ ├── import.test.js
│ │ │ ├── index.test.js
│ │ │ ├── kendraIndex.test.js
│ │ │ ├── mockedContext.js
│ │ │ ├── settings.test.js
│ │ │ ├── testall.test.js
│ │ │ └── util.test.js
│ │ ├── data/
│ │ │ ├── actions/
│ │ │ │ ├── add.test.js
│ │ │ │ ├── delete.test.js
│ │ │ │ ├── get.test.js
│ │ │ │ ├── up-download.test.js
│ │ │ │ └── util.test.js
│ │ │ ├── getters.test.js
│ │ │ └── mutations.test.js
│ │ ├── page/
│ │ │ ├── actions.test.js
│ │ │ ├── getters.test.js
│ │ │ ├── mutations.test.js
│ │ │ └── util.test.js
│ │ └── user/
│ │ ├── actions.test.js
│ │ ├── getters.test.js
│ │ ├── index.test.js
│ │ └── mutations.test.js
│ ├── resolver.js
│ ├── styleMock.js
│ └── test.test.js
├── assets/
│ └── zombie.json
├── config/
│ ├── base.config.js
│ ├── dev.config.js
│ ├── prod.config.js
│ ├── test.config.js
│ └── webpack.config.js
├── entry.js
├── html/
│ ├── admin.pug
│ ├── client.pug
│ └── test.ejs
├── js/
│ ├── admin.js
│ ├── admin.vue
│ ├── browser-check.js
│ ├── capability/
│ │ └── util.js
│ ├── client.js
│ ├── client.vue
│ ├── components/
│ │ ├── alexa/
│ │ │ ├── index.vue
│ │ │ └── steps.js
│ │ ├── connect/
│ │ │ ├── index.vue
│ │ │ └── steps.js
│ │ ├── customTranslate.vue
│ │ ├── designer/
│ │ │ ├── add.vue
│ │ │ ├── addSetting.vue
│ │ │ ├── alexa.vue
│ │ │ ├── delete.vue
│ │ │ ├── display.vue
│ │ │ ├── edit.vue
│ │ │ ├── empty.js
│ │ │ ├── event-bus.js
│ │ │ ├── index.vue
│ │ │ ├── input.vue
│ │ │ ├── menu-questions.vue
│ │ │ ├── menu-test.vue
│ │ │ ├── menu-testall.vue
│ │ │ ├── modal.vue
│ │ │ ├── qa.vue
│ │ │ ├── rebuild.vue
│ │ │ └── synckendra.vue
│ │ ├── export.vue
│ │ ├── genesys/
│ │ │ ├── index.vue
│ │ │ └── steps.js
│ │ ├── hooks/
│ │ │ ├── codejs.txt
│ │ │ ├── codepy.txt
│ │ │ ├── example.js
│ │ │ ├── index.vue
│ │ │ └── steps.js
│ │ ├── import.vue
│ │ ├── kendraIndex.vue
│ │ ├── loading.vue
│ │ └── settings.vue
│ ├── lib/
│ │ ├── client-auth.js
│ │ ├── index.js
│ │ ├── router.js
│ │ ├── store/
│ │ │ ├── actions.js
│ │ │ ├── api/
│ │ │ │ ├── actions/
│ │ │ │ │ ├── connect.js
│ │ │ │ │ ├── export.js
│ │ │ │ │ ├── genesys.js
│ │ │ │ │ ├── import.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── kendraIndex.js
│ │ │ │ │ ├── settings.js
│ │ │ │ │ ├── testall.js
│ │ │ │ │ └── tmp.js
│ │ │ │ ├── card-schema.json
│ │ │ │ ├── index.js
│ │ │ │ └── schema.json
│ │ │ ├── data/
│ │ │ │ ├── actions/
│ │ │ │ │ ├── add.js
│ │ │ │ │ ├── delete.js
│ │ │ │ │ ├── get.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── schema.json
│ │ │ │ │ ├── up-download.js
│ │ │ │ │ └── util.js
│ │ │ │ ├── getters.js
│ │ │ │ ├── index.js
│ │ │ │ └── mutations.js
│ │ │ ├── getters.js
│ │ │ ├── index.js
│ │ │ ├── mutations.js
│ │ │ ├── page/
│ │ │ │ ├── actions.js
│ │ │ │ ├── getters.js
│ │ │ │ ├── index.js
│ │ │ │ ├── mutations.js
│ │ │ │ └── util.js
│ │ │ └── user/
│ │ │ ├── actions.js
│ │ │ ├── getters.js
│ │ │ ├── index.js
│ │ │ ├── mutations.js
│ │ │ └── schema.json
│ │ └── validator.js
│ └── test.js
├── style/
│ └── app.styl
└── styles/
├── app.css
├── fonts/
│ └── material-icons.css
├── pure-min.css
└── vuetify-min.css
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Please complete the following information about the solution:**
- [ ] Version: [e.g. v0.0.1]
To get the version of the solution, you can look at the description of the created CloudFormation stack. For example, "_(SO0189) QnABot [...] **v0.0.1**_".
- [ ] Region: [e.g. us-east-1]
- [ ] Was the solution modified from the version published on this repository?
- [ ] If the answer to the previous question was yes, are the changes available on GitHub?
- [ ] Have you checked your [service quotas](https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html) for the services this solution uses?
- [ ] Were there any errors in the CloudWatch Logs?
**Screenshots**
If applicable, add screenshots to help explain your problem (please **DO NOT include sensitive information**).
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/ISSUE_TEMPLATE/conditional_chaining.md
================================================
---
name: Conditional Chaining Expression Request
about: Request support for new conditional chaining expressions or operators
title: ''
labels: conditional-chaining, enhancement
assignees: ''
---
**Describe the expression you'd like to use**
A clear description of what you're trying to accomplish with conditional chaining.
**Requested Expression**
Please provide the exact conditional chaining expression you'd like to use:
```
[Paste your desired conditional chaining expression here]
```
**Use Case**
Describe your use case and why this expression would be helpful.
**Solution Version**
- [ ] Version: [e.g. v7.3.0]
To get the version of the solution, you can look at the description of the created CloudFormation stack. For example, "_(SO0189) QnABot [...] **v7.3.0**_".
**Additional context**
Add any other context about the request here.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this solution
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the feature you'd like**
A clear and concise description of what you want to happen.
**Additional context**
Add any other context or screenshots about the feature request here.
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
*Issue #, if available:*
*Description of changes:*
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
================================================
FILE: .gitignore
================================================
build
codescan-*
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
py_modules/
crhelper*/
model_repo/
.pytest_cache/
__pycache__/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
build
source/config.json
**/.DS_Store
.idea/
# ignore VS Code specific configs and environments
.devcontainer/
.vscode/
utilities/migration.md
# Temporary folders and backup files
tmp/
temp/
*.bak
# derived build assets
**/deployment/global-s3-assets
**/deployment/regional-s3-assets
**/deployment/open-source
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
**/coverage/
**/coverage-reports/
lcov.info
lib-cov
.nyc_output
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
**/.venv-test/
docs/excel_import/~$sample.xlsx
.nightswatch/functional/files/~$import-pass.xlsx
.nightswatch/functional/files/~$import-fail.xlsx
# pipenv lock files
Pipfile
Pipfile.lock
# We are using default .viperlightrc. No need to keep this in the repo.
.viperlightrc
# Lambda requirements.txt files
**/requirements.txt
.aider*
.kiro
================================================
FILE: .nightswatch/functional/conftest.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
import pytest
import os
import logging
import string
import secrets
from packaging import version
log = logging.getLogger(__name__)
from helpers.cfn_parameter_fetcher import ParameterFetcher
from helpers.kendra_client import KendraClient
from helpers.lex_client import LexClient
from helpers.iam_client import IamClient
from helpers.s3_client import S3Client
from helpers.translate_client import TranslateClient
from helpers.cloud_watch_client import CloudWatchClient
from helpers.website_model.dom_operator import DomOperator
from helpers.website_model.login_page import LoginPage
def get_password() -> str:
cognito_special_characters = '^$*.[]{}()?-"!@#%&,><:;|_~+='
def is_special(c):
for s in cognito_special_characters:
if s == c:
return True
return False
alphabet = string.ascii_letters + string.digits + cognito_special_characters
while True:
password = ''.join(secrets.choice(alphabet) for i in range(10))
if (any(c.islower() for c in password)
and any(c.isupper() for c in password)
and sum(c.isdigit() for c in password) >= 3
and any(is_special(c) for c in password)):
return password
temp_pass = get_password()
new_pass = get_password()
@pytest.fixture
def region() -> str:
return os.environ.get('CURRENT_STACK_REGION')
@pytest.fixture
def stack_name() -> str:
return os.environ.get('CURRENT_STACK_NAME')
@pytest.fixture
def username() -> str:
if os.environ.get('USER'):
return os.environ.get('USER')
return 'QnaAdmin'
@pytest.fixture
def email() -> str:
email = os.environ.get("EMAIL", "")
return email
@pytest.fixture
def temporary_password() -> str:
return temp_pass
@pytest.fixture
def password() -> str:
if os.environ.get('PASSWORD'):
return os.environ.get('PASSWORD')
return new_pass
@pytest.fixture
def languages() -> list['str']:
return ['fr', 'es']
@pytest.fixture
def param_fetcher(region: str, stack_name: str) -> ParameterFetcher:
return ParameterFetcher(region, stack_name)
@pytest.fixture
def kendra_client(region: str, param_fetcher: ParameterFetcher) -> KendraClient:
return KendraClient(region, param_fetcher.get_kendra_faq_index(), param_fetcher.get_kendra_webpage_index())
@pytest.fixture
def lex_client(region: str) -> LexClient:
return LexClient(region)
@pytest.fixture
def translate_client(region: str) -> TranslateClient:
return TranslateClient(region)
@pytest.fixture
def iam_client(region: str) -> IamClient:
return IamClient(region)
@pytest.fixture
def s3_client(region: str) -> None:
return S3Client(region)
@pytest.fixture
def app_version(param_fetcher: ParameterFetcher) -> str:
app_version = param_fetcher.get_deployment_version()
return app_version
@pytest.fixture(autouse=True)
def skip_if_version_less_than(request, app_version):
if request.node.get_closest_marker('skipif_version_less_than'):
marker = request.node.get_closest_marker('skipif_version_less_than')
expected_version = marker.args[0]
if version.parse(app_version) < version.parse(expected_version):
pytest.skip(f'App Version {app_version} is less than expected version {expected_version}. Skipping...')
@pytest.fixture
def cw_client(region: str, param_fetcher: ParameterFetcher) -> CloudWatchClient:
stack_id = param_fetcher.get_stack_id()
stack_name = param_fetcher.stack_name
return CloudWatchClient(region, stack_id, stack_name)
@pytest.fixture(autouse=True)
def dom_operator():
dom_operator = DomOperator()
yield dom_operator
dom_operator.end_session()
@pytest.fixture
def invalid_designer_login(dom_operator: DomOperator, param_fetcher: ParameterFetcher, username: str, password: str):
designer_url = param_fetcher.get_designer_url()
login_page = LoginPage(dom_operator, designer_url)
password = 'invalidPassword'
return login_page.login(username, password)
@pytest.fixture
def designer_login(dom_operator: DomOperator, param_fetcher: ParameterFetcher, username: str, password: str):
designer_url = param_fetcher.get_designer_url()
login_page = LoginPage(dom_operator, designer_url)
return login_page.login(username, password)
@pytest.fixture
def client_login(dom_operator: DomOperator, param_fetcher: ParameterFetcher, username: str, password: str):
client_url = param_fetcher.get_client_url()
login_page = LoginPage(dom_operator, client_url)
return login_page.login(username, password)
@pytest.fixture
def invalid_client_login(dom_operator: DomOperator, param_fetcher: ParameterFetcher, username: str, password: str):
client_url = param_fetcher.get_client_url()
login_page = LoginPage(dom_operator, client_url)
password = 'invalidPassword'
return login_page.login(username, password)
@pytest.fixture
def lambda_hook_example_arn(dom_operator: DomOperator, param_fetcher: ParameterFetcher, username: str, password: str) -> str:
return param_fetcher.get_lambda_hook_example_arn().split(':')[-1]
test_time_flag = os.environ.get('TIMESTAMPS')
if test_time_flag:
@pytest.fixture(autouse=True, scope='function')
def log_timestamps(request):
log.info(f"{request.node.cls} {request.node.name} start.")
yield
log.info(f"{request.node.cls} {request.node.name} end.")
@pytest.fixture
def kendra_is_enabled(param_fetcher: ParameterFetcher):
return param_fetcher.kendra_is_enabled()
@pytest.fixture(autouse=True)
def skip_kendra(request, kendra_is_enabled):
if request.node.get_closest_marker('skipif_kendra_not_enabled'):
# if True:
if not kendra_is_enabled:
pytest.skip('Kendra is not configured for this environment. Skipping...')
@pytest.fixture
def knowledge_base_is_enabled(param_fetcher: ParameterFetcher):
return param_fetcher.bedrock_knowledge_base_is_enabled()
@pytest.fixture(autouse=True)
def skip_knowledge_base(request, knowledge_base_is_enabled):
if request.node.get_closest_marker('skipif_knowledge_base_not_enabled'):
# if True:
if not knowledge_base_is_enabled:
pytest.skip('Knowledge bases are not configured for this environment. Skipping...')
@pytest.fixture
def llm_is_enabled(param_fetcher: ParameterFetcher):
return param_fetcher.llm_is_enabled()
@pytest.fixture(autouse=True)
def skip_llm(request, llm_is_enabled):
if request.node.get_closest_marker('skipif_llm_not_enabled'):
# if True:
if not llm_is_enabled:
pytest.skip('An LLM is not configured for this environment. Skipping...')
@pytest.fixture
def embeddings_is_enabled(param_fetcher: ParameterFetcher):
return param_fetcher.embeddings_is_enabled()
@pytest.fixture(autouse=True)
def skip_embeddings(request, embeddings_is_enabled):
if request.node.get_closest_marker('skipif_embeddings_not_enabled'):
# if True:
if not embeddings_is_enabled:
pytest.skip('Embeddings is not configured for this environment. Skipping...')
@pytest.fixture
def knowledge_base_model(param_fetcher: ParameterFetcher):
return param_fetcher.get_bedrock_knowledge_base_model()
@pytest.fixture
def content_designer_output_bucket_name(param_fetcher: ParameterFetcher):
return param_fetcher.get_content_designer_output_bucket_name()
================================================
FILE: .nightswatch/functional/files/EPCTerminology.csv
================================================
en,es
without incurring any fees, sin incurrir ningún cargo
================================================
FILE: .nightswatch/functional/files/import-fail-expected.json
================================================
{
"qna": [
{
"a": "You cannot leave your QID blank",
"type": "qna",
"qid": "",
"q": [
"Can I leave my QID Blank?"
]
},
{
"a": "You cannot have spaces in your Item ID, Quiz Question ID, or Slot type name.",
"type": "qna",
"qid": "No Spaces.001",
"q": [
"Can I add spaces in my qid?"
]
},
{
"a": "You cannot have an with no question",
"type": "qna",
"qid": "NoQuestion.001",
"q": []
},
{
"a": "",
"type": "qna",
"qid": "NoAnswer.001",
"q": [
"Can I have a question but no answer?"
]
},
{
"a": "Questions/Utterances with over 140 Characters cannot be imported",
"type": "qna",
"qid": "QuestionCharLimit.001",
"q": [
"What will happen if I try to import a .json and/or excel (.xlsx) file containing a question/utterance with over 140 characters like this one?"
]
}
]
}
================================================
FILE: .nightswatch/functional/files/import-pass-expected.json
================================================
{
"qna": [
{
"a": "From the import page.",
"r": {
"buttons": [
{
"text": "Tell me about the Alexa Show.",
"value": "The Echo Show"
},
{
"text": "Tell me about the Echo Dot",
"value": "The Echo Dot"
}
],
"imageUrl": "https://images-na.ssl-images-amazon.com/images/I/61bze1WJhfL._AC_SL1024_.jpg",
"title": "Alexa"
},
"t": "import",
"elicitResponse": {
"responsebot_hook": "QnAYesNoBot"
},
"alt": {
"markdown": "*From the import page.*",
"ssml": "<speak>From the import page.</speak>"
},
"type": "qna",
"qid": "Import.002",
"sa": [
{
"enableTranslate": false,
"text": "TestName",
"value": "TestValue"
},
{
"enableTranslate": true,
"text": "TestName2",
"value": "TestValue2"
}
],
"clientFilterValues": "Test",
"q": [
"How do I import questions in content designer?",
"How do I import questions using QnA Bot?"
]
},
{
"a": "Of course!",
"type": "qna",
"qid": "Import.003",
"q": [
"Can I import multiple answers when I import with excel?",
"Can I import multiple answers when I import with excel using QnA Bot?"
]
},
{
"a": "今日は晴れです。",
"type": "qna",
"qid": "DoubleByteCharacters.001",
"q": [
"今日の天気を教えてください."
]
}
]
}
================================================
FILE: .nightswatch/functional/files/terms.csv
================================================
en,fr,es
custom terminology,custom terminology,custom terminology
================================================
FILE: .nightswatch/functional/helpers/__init__.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
================================================
FILE: .nightswatch/functional/helpers/bot_intents/get_attribute.json
================================================
{
"intentName": "GetAttribute",
"localeId": "en_US",
"sampleUtterances": [
{
"utterance": "Do I have an attribute?"
}
],
"initialResponseSetting": {
"conditional": {
"active": true,
"conditionalBranches": [
{
"condition": {
"expressionString": "[myAttribute] = \"test\""
},
"name": "hasAttribute",
"nextStep": {
"dialogAction": {
"type": "EndConversation"
}
},
"response": {
"allowInterrupt": true,
"messageGroups": [
{
"message": {
"plainTextMessage": {
"value": "TRUE - YOUR ATTRIBUTE IS CONFIGURED CORRECTLY."
}
}
}
]
}
}
],
"defaultBranch": {
"nextStep": {
"dialogAction": {
"type": "EndConversation"
}
},
"response": {
"allowInterrupt": true,
"messageGroups": [
{
"message": {
"plainTextMessage": {
"value": "FALSE - YOUR ATTRIBUTE IS NOT CONFIGURED CORRECTLY"
}
}
}
]
}
}
}
}
}
================================================
FILE: .nightswatch/functional/helpers/bot_intents/greetings.json
================================================
{
"intentName": "sayHello",
"localeId": "en_US",
"sampleUtterances": [
{
"utterance": "Hello"
},
{
"utterance": "Hi"
},
{
"utterance": "Greetings"
}
],
"fulfillmentCodeHook": {
"active": true,
"enabled": false,
"postFulfillmentStatusSpecification": {
"failureResponse": {
"allowInterrupt": true,
"messageGroups": [
{
"message": {
"plainTextMessage": {
"value": "I BROKE"
}
}
}
]
},
"successResponse": {
"allowInterrupt": true,
"messageGroups": [
{
"message": {
"plainTextMessage": {
"value": "GREETINGS, I AM TEST BOT. "
}
}
}
]
}
}
}
}
================================================
FILE: .nightswatch/functional/helpers/bot_intents/set_attribute.json
================================================
{
"intentName": "SetAttribute",
"localeId": "en_US",
"sampleUtterances": [
{
"utterance": "Give me an attribute"
}
],
"initialResponseSetting": {
"initialResponse": {
"messageGroups": [
{
"message": {
"plainTextMessage": {
"value": "HERE IS A SESSION ATTRIBUTE."
}
}
}
]
},
"nextStep": {
"dialogAction": {
"type": "EndConversation"
},
"sessionAttributes": {
"botAttribute" : "test"
}
}
}
}
================================================
FILE: .nightswatch/functional/helpers/cfn_parameter_fetcher.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
from typing import Optional
import boto3
import re
import os
class ParameterFetcher:
"""
A Python class to interact with AWS CloudFormation using Boto3.
This class provides various methods to fetch details related to the specified stack.
"""
def __init__(self, region: str, stack_name: str) -> None:
"""
Constructs all the necessary attributes for the ParameterFetcher object.
Parameters:
----------
region : str
AWS region name where the CloudFormation stack exists.
stack_name : str
The name of the CloudFormation stack.
"""
self.region = region
self.stack_name = stack_name
profile_name = os.environ.get('TEST_ACCOUNT_PROFILE_NAMES')
if profile_name is not None and profile_name != '':
boto3.setup_default_session(profile_name=profile_name)
self.cloudformation_client = boto3.client('cloudformation', region_name=region)
def get_user_pool_id(self) -> Optional[str]:
"""
Retrieves the User Pool ID from the stack resources.
Returns:
-------
The User Pool ID if found, otherwise None.
"""
response = self.cloudformation_client.list_stack_resources(
StackName=self.stack_name
)
while True:
for StackResourceSummary in response['StackResourceSummaries']:
if StackResourceSummary['LogicalResourceId'] == 'UserPool':
user_pool_id = StackResourceSummary['PhysicalResourceId']
return user_pool_id
if 'NextToken' in response:
response = self.cloudformation_client.list_stack_resources(
StackName=self.stack_name,
NextToken=response['NextToken']
)
else:
raise RuntimeError('User Pool ID not found.')
def __get_cfn_param(self, key: str) -> Optional[str]:
"""
Retrieves the key value from the stack parameters.
Returns:
-------
The value if found, otherwise None.
"""
response = self.cloudformation_client.describe_stacks(
StackName=self.stack_name
)
stacks = response['Stacks']
for stack in stacks:
parameters = stack['Parameters']
for parameter in parameters:
if parameter['ParameterKey'] == key:
parameter_value = parameter['ParameterValue']
return parameter_value
def __get_stack_description(self) -> Optional[str]:
"""
Retrieves the stack description.
Returns:
-------
The stack description.
"""
response = self.cloudformation_client.describe_stacks(
StackName=self.stack_name
)
return response['Stacks'][0]['Description']
def __get_resource_name_from_logical_id(self, logical_id: str) -> Optional[str]:
"""
Retrieves the resource name from the stack resources.
Returns:
-------
The resource name if found.
"""
response = self.cloudformation_client.describe_stack_resource(
StackName=self.stack_name,
LogicalResourceId=logical_id
)
return response['StackResourceDetail']['PhysicalResourceId']
def __get_stack_outputs(self, key: str) -> Optional[str]:
"""
Retrieves the stack outputs using the key provided.
Returns:
-------
The stack outputs.
"""
describe_stack = self.cloudformation_client.describe_stacks(StackName=self.stack_name)
stack_outputs = describe_stack['Stacks'][0]['Outputs']
for output in stack_outputs:
if output['OutputKey'] == key:
return output['OutputValue']
def get_kendra_webpage_index(self) -> Optional[str]:
"""
Retrieves the Kendra Index from the stack parameters.
Returns:
-------
The Kendra Index if found, otherwise None.
"""
return self.__get_cfn_param('KendraWebPageIndexId')
def get_kendra_faq_index(self) -> Optional[str]:
"""
Retrieves the Kendra Index from the stack parameters.
Returns:
-------
The Kendra Index if found, otherwise None.
"""
return self.__get_cfn_param('KendraFaqIndexId')
def get_bedrock_knowledge_base_id(self) -> Optional[str]:
"""
Retrieves the ID of the Bedrock Knowledge Base from the stack parameters.
Returns:
-------
The Knowledge Base ID if found, otherwise None.
"""
knowledge_base_id = self.__get_cfn_param('BedrockKnowledgeBaseId')
return knowledge_base_id
def get_designer_client_id(self) -> Optional[str]:
"""
Retrieves the Designer Client ID from the stack resources.
Returns:
-------
The Designer Client ID if found, otherwise None.
"""
response = self.cloudformation_client.list_stack_resources(
StackName=self.stack_name
)
for StackResourceSummary in response['StackResourceSummaries']:
if StackResourceSummary['LogicalResourceId'] == 'ClientDesigner':
designer_client_id = StackResourceSummary['PhysicalResourceId']
return designer_client_id
def get_designer_url(self) -> Optional[str]:
"""
Retrieves the Content Designer URL from the stack outputs.
Returns:
-------
The Content Designer URL if found, otherwise None.
"""
return self.__get_stack_outputs('ContentDesignerURL')
def get_client_url(self) -> Optional[str]:
"""
Retrieves the Client URL from the stack outputs.
Returns:
-------
The Client URL if found, otherwise None.
"""
return self.__get_stack_outputs('ClientURL')
def kendra_is_enabled(self) -> bool:
"""
Identifies if the Kendra is configured for the deployment.
Returns:
-------
True if the kendra index is set.
"""
kendra_index_id = self.get_kendra_faq_index()
return kendra_index_id != None and kendra_index_id != ''
def bedrock_knowledge_base_is_enabled(self) -> bool:
"""
Identifies if a Bedrock Knowledge Base is configured for the deployment.
Returns:
-------
True if the knowledge base parameter is set.
"""
bedrock_knowledge_base = self.get_bedrock_knowledge_base_id()
return bedrock_knowledge_base != None and bedrock_knowledge_base != ''
def llm_is_enabled(self) -> bool:
"""
Identifies if an LLM is deployed.
Returns:
-------
True if an LLM is configured.
"""
llm_api_param = self.__get_cfn_param('LLMApi')
return llm_api_param != None and llm_api_param != 'DISABLED'
def embeddings_is_enabled(self) -> bool:
"""
Identifies if embeddings is deployed.
Returns:
-------
True if embeddings is configured.
"""
embeddings_api_param = self.__get_cfn_param('EmbeddingsApi')
return embeddings_api_param != None and embeddings_api_param != 'DISABLED'
def get_fulfillment_lambda_name(self) -> str:
"""
Retrieves the name of the fulfillment lambda.
Returns:
-------
The name of the fulfillment lambda.
"""
return self.__get_resource_name_from_logical_id('FulfillmentLambda')
def get_deployment_version(self) -> str:
"""
Retrieves the deployment version from the stack description.
Returns:
-------
The deployment version.
"""
description = self.__get_stack_description()
version = re.search(r'Version v\s*([\d.]+)', description).group(1)
return version
def get_lambda_hook_example_arn(self) -> str:
"""
Retrieves the ARN of the lambda hook example.
Returns:
-------
The ARN of the lambda hook example.
"""
examples_stack_name = self.__get_resource_name_from_logical_id('ExamplesStack')
examples_stack_param_fetcher = ParameterFetcher(self.region, examples_stack_name)
return examples_stack_param_fetcher.__get_stack_outputs('EXTCustomJSHook')
def get_stack_id(self) -> Optional[str]:
"""
Retrieves the stack id.
Returns:
-------
The stack id.
"""
response = self.cloudformation_client.describe_stacks(
StackName=self.stack_name
)
stack_id = response['Stacks'][0]['StackId'].split('/')[2]
return stack_id
def get_bedrock_knowledge_base_model(self) -> Optional[str]:
"""
Retrieves the model of the Bedrock Knowledge Base from the stack parameters.
Returns:
-------
The Knowledge Base Model if found, otherwise None.
"""
knowledge_base_model = self.__get_cfn_param('BedrockKnowledgeBaseModel')
return knowledge_base_model
def get_content_designer_output_bucket_name(self) -> Optional[str]:
"""
Retrieves the name of the test all output bucket from the stack parameters.
Returns:
-------
The name of the test all bucket if found, otherwise None.
"""
return self.__get_stack_outputs('ContentDesignerOutputBucket')
================================================
FILE: .nightswatch/functional/helpers/cloud_watch_client.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
# A client that connects with AWS CloudWatch and returns logs from log groups from a specific time period
import boto3
import time
import datetime
class CloudWatchClient:
"""
Interacts with CloudWatch using Boto3.
This class provides methods for pulling logs from log groups based on matches.
"""
def __init__(self, region: str, stack_id: str, stack_name: str):
"""
Initializes the CloudWatchClient.
:param region: The AWS region to connect to.
:type region: st
"""
self.client = boto3.client('logs', region_name=region)
self.region = region
self.fulfillment_lambda_log_group = f'/aws/lambda/{stack_name}-FulfillmentLambda-{stack_id}'
self.start_time = int(time.time() * 1000)
def __get_logs(self, log_group_name: str, start_time: int, filter_pattern: str) -> dict:
"""
Gets logs from a log group.
:param log_group_name: The name of the log group.
:param start_time: The start time of the logs.
:param end_time: The end time of the logs.
:return: The logs.
:rtype: dict
"""
response = self.client.filter_log_events(
logGroupName=log_group_name,
startTime=start_time,
filterPattern=filter_pattern,
limit=20
)
return response
def print_logs(self, log_group_name: str, filter_pattern: str='') -> dict:
"""
Prints logs from a given log group from the time of the start of the test to current.
:param log_group_name: Log group name.
:param filter_pattern: CloudWatch filter pattern.
"""
# Wait for CloudWatch logs to be available
time.sleep(10)
print(f'----- Printing log group {log_group_name} from: {datetime.datetime.utcfromtimestamp(self.start_time/1000).strftime("%c")} to: {datetime.datetime.utcfromtimestamp(time.time()).strftime("%c")} -----')
response = self.__get_logs(log_group_name, self.start_time, filter_pattern)
for event in response['events']:
print(event['message'])
def print_fulfillment_lambda_logs(self, filter_pattern: str='?TypeError ?InvokeError ?"Invoke Error"') -> dict:
"""
Prints logs from the fulfillment lambda function.
:param filter_pattern: CloudWatch filter pattern.
"""
self.print_logs(self.fulfillment_lambda_log_group, filter_pattern)
================================================
FILE: .nightswatch/functional/helpers/cognito_client.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
import boto3
from botocore.exceptions import ClientError
import time
class CognitoClient:
"""
A Python class to interact with AWS Cognito using Boto3.
This class provides various methods to manage users in a Cognito User Pool.
"""
def __init__(self, region: str, user_pool_id: str, client_id: str) -> None:
"""
Constructs all the necessary attributes for the CognitoClient object.
Parameters:
----------
region : str
AWS region name where the Cognito User Pool exists.
user_pool_id : str
The ID of the Cognito User Pool.
client_id : str
The ID of the Cognito User Pool Client.
"""
self.user_pool_id = user_pool_id
self.client_id = client_id
self.cognito_idp_client = boto3.client('cognito-idp', region_name=region)
def create_admin_user(self, username: str, temporary_password: str, email: str) -> None:
"""
Creates a new admin user if the user doesn't already exist in the Cognito User Pool.
Parameters:
----------
username : str
The username for the new user.
temporary_password : str
The temporary password for the new user.
email : str
The email of the new user.
"""
self.cognito_idp_client.admin_create_user(
UserPoolId=self.user_pool_id,
Username=username,
UserAttributes=[
{
'Name': 'email',
'Value': email
},
{
'Name': 'email_verified',
'Value': 'True'
}
],
TemporaryPassword=temporary_password,
ForceAliasCreation=True
)
self.cognito_idp_client.admin_add_user_to_group(
UserPoolId=self.user_pool_id,
Username=username,
GroupName='Admins'
)
def delete_admin_user(self, username: str) -> None:
"""
Deletes an admin user from the Cognito User Pool.
Parameters:
----------
username : str
The username of the user to delete.
"""
self.cognito_idp_client.admin_delete_user(
UserPoolId=self.user_pool_id,
Username=username
)
def create_admin_and_set_password(self, username: str, temporary_password: str, new_password: str, email: str) -> int:
"""
Creates a new admin user with the given username if the user doesn't already exist.
Parameters:
----------
username : str
The username of the user.
temporary_password : str
The temporary password of the user.
new_password : str
The new password for the user.
email : str
The email of the user.
Returns:
-------
The HTTP status code of the response to the AdminRespondToAuthChallenge request.
"""
try:
self.create_admin_user(username, temporary_password, email)
response_admin_initiate_auth = self.cognito_idp_client.admin_initiate_auth(
UserPoolId=self.user_pool_id,
ClientId=self.client_id,
AuthFlow='ADMIN_NO_SRP_AUTH',
AuthParameters={
'USERNAME': username,
'PASSWORD': temporary_password
}
)
session = response_admin_initiate_auth['Session']
response_admin_respond_to_auth_challenge = self.cognito_idp_client.admin_respond_to_auth_challenge(
UserPoolId=self.user_pool_id,
ClientId=self.client_id,
ChallengeName='NEW_PASSWORD_REQUIRED',
ChallengeResponses={
'USERNAME': username,
'NEW_PASSWORD': new_password
},
Session=session
)
return response_admin_respond_to_auth_challenge['ResponseMetadata']['HTTPStatusCode']
except ClientError as e:
if e.response['Error']['Code'] == 'UsernameExistsException':
print('User already exists')
self.delete_admin_user(username)
time.sleep(5) # Wait for 5 seconds before trying to create the user again.
return self.create_admin_and_set_password(username, temporary_password, new_password, email)
else:
raise e
================================================
FILE: .nightswatch/functional/helpers/iam_client.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
import boto3
import json
class IamClient:
"""
A Python class to interact with Amazon IAM using Boto3.
This class provides various methods to perform operations on IAM.
"""
def __init__(self, region: str) -> None:
"""
Initializes the IamClient class.
Args:
region (str): The AWS region to connect to.
Returns:
None.
Raises:
None.
"""
self.iam_client = boto3.client('iam', region_name=region)
def create_role(self, role_name: str, trust_relationship: dict) -> dict:
"""
Creates an IAM role.
Args:
role_name (str): The name of the role to create.
trust_relationship (dict): The trust relationship for the role.
Returns:
dict: The response from the create_role API call.
Raises:
None.
"""
return self.iam_client.create_role(
RoleName=role_name,
AssumeRolePolicyDocument=trust_relationship
)
def attach_policy(self, policy_arn: str, role_name: str) -> dict:
"""
Attaches an IAM policy to a role.
Args:
policy_arn (str): The ARN of the policy to attach.
role_name (str): The name of the role to attach the policy to.
Returns:
dict: The response from the attach_policy API call.
Raises:
None.
"""
return self.iam_client.attach_role_policy(
PolicyArn=policy_arn,
RoleName=role_name
)
def create_lexv2_role(self, bot_name) -> str:
"""
Creates an Amazon Lex V2 role.
Args:
bot_name: The name of the bot.
Returns:
str: The name of the role.
Raises:
None.
"""
role_name = f'lex_bot_role_{bot_name}'
trust_relationship = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lexv2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
# policy_arn = 'arn:aws:iam::aws:policy/aws-service-role/AmazonLexV2BotPolicy'
self.delete_role_if_exists(role_name)
response = self.create_role(role_name, json.dumps(trust_relationship))
role_arn = response['Role']['Arn']
# self.attach_policy(policy_arn, role_name)
return role_arn
def delete_role_if_exists(self, role_name: str) -> None:
"""
Deletes an IAM role if it exists.
Args:
role_name (str): The name of the role to delete.
Returns:
None.
Raises:
None.
"""
try:
self.iam_client.delete_role(RoleName=role_name)
except:
pass
================================================
FILE: .nightswatch/functional/helpers/kendra_client.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
import boto3
class KendraClient:
"""
A Python class to interact with Amazon Kendra using Boto3.
This class provides various methods to perform operations on Kendra.
"""
def __init__(self, region: str, faq_index: str, webpage_index: str) -> None:
"""
Constructs all the necessary attributes for the KendraClient object.
Parameters:
----------
region : str
AWS region name where the Kendra instance exists.
index : str
The index ID of Amazon Kendra.
"""
self.faq_index = faq_index
self.webpage_index = webpage_index
self.kendra_client = boto3.client('kendra', region_name=region)
def list_faqs(self) -> dict:
"""
Lists all FAQs for the given Amazon Kendra index.
Returns:
-------
A dict containing the response from the ListFaqs operation.
"""
return self.kendra_client.list_faqs(IndexId=self.faq_index)
def delete_faq_by_id(self, id: str) -> dict:
"""
Deletes a specific FAQ based on its ID.
Parameters:
----------
id : str
The ID of the FAQ to delete.
Returns:
-------
A dict containing the response from the DeleteFaq operation.
"""
return self.kendra_client.delete_faq(Id=id, IndexId=self.faq_index)
def list_data_sources(self) -> dict:
"""
Lists all data sources for the given Amazon Kendra index.
Returns:
-------
A dict containing the response from the ListDataSources operation.
"""
return self.kendra_client.list_data_sources(IndexId=self.webpage_index)
def query(self, query: str) -> dict:
"""
Searches an index given an input query.
Returns:
-------
A dict containing the response from the Query operation.
"""
return self.kendra_client.query(IndexId=self.webpage_index, QueryText=query)
================================================
FILE: .nightswatch/functional/helpers/lex_client.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
import boto3
import json
import time
from botocore.exceptions import ClientError
class LexClient:
"""
Class representing a Lex Bot Client.
This class provides methods to interact with an AWS Lex bot, such as retrieving its properties
and verifying the presence or absence of slot types.
Attributes:
lex_client (botocore.client.LexModelBuildingService): An instance of Boto3 Lex client.
"""
def __init__(self, region: str) -> None:
"""
Initializes the LexClient with a specific AWS region.
Args:
region (str): The AWS region to associate the Lex bot client.
"""
self.lex_client = boto3.client('lexv2-models', region_name=region)
def __get_bot_id_version(self, bot_name) -> tuple:
"""
Private method to get the bot ID and latest version for a specific bot.
Args:
bot_name (str): The name of the bot.
Returns:
tuple: The bot ID and latest version of the bot.
"""
response = self.lex_client.list_bots(
filters=[
{
'name': 'BotName',
'values': [
bot_name,
],
'operator': 'EQ'
},
],
)
while True:
for bot_summary in response['botSummaries']:
if bot_summary['botName'] == bot_name:
return bot_summary['botId'], bot_summary['latestBotVersion']
if 'nextToken' in response:
response = self.lex_client.list_bots(
nextToken=response['nextToken'],
filters=[
{
'name': 'BotName',
'values': [
bot_name,
],
'operator': 'EQ'
},
],
)
else:
raise RuntimeError(f'Bot with name "{bot_name}" not found.')
def __list_slot_type_names(self, id: str, version: str, locale: str) -> list[str]:
"""
Private method to list the slot type names for a specific bot.
Args:
id (str): The ID of the bot.
version (str): The version of the bot.
locale (str): The locale for the bot.
Returns:
list[str]: The list of slot type names.
"""
response = self.lex_client.list_slot_types(
botId=id,
botVersion=version,
localeId=locale
)
return [slot_type['slotTypeName'] for slot_type in response['slotTypeSummaries']]
def bot_slot_type_names_exist_for_all_locales(self, bot_name: str, slot_type_names: list[str], locales: list[str]=['en_US']) -> bool:
"""
Checks if the specified slot type names exist for all the locales of a specific bot.
Args:
bot_name (str): The name of the bot.
slot_type_names (list[str]): The list of slot type names to check.
locales (list[str], optional): The list of locales to check. Defaults to ['en_US'].
Returns:
bool: True if all the slot type names exist for all locales, False otherwise.
"""
bot_id, version = self.__get_bot_id_version(bot_name)
return all([set(slot_type_names) <= set(self.__list_slot_type_names(bot_id, version, locale)) for locale in locales])
def bot_slot_type_names_do_not_exist_for_all_locales(self, bot_name: str, slot_type_names: list[str], locales: list[str]=['en_US']) -> bool:
"""
Checks if the specified slot type names do not exist for all the locales of a specific bot.
Args:
bot_name (str): The name of the bot.
slot_type_names (list[str]): The list of slot type names to check.
locales (list[str], optional): The list of locales to check. Defaults to ['en_US'].
Returns:
bool: True if none of the slot type names exist for all locales, False otherwise.
"""
bot_id, version = self.__get_bot_id_version(bot_name)
for locale in locales:
if any(slot in slot_type_names for slot in self.__list_slot_type_names(bot_id, version, locale)):
return False
return True
def create_test_bot(self, bot_name: str, role_arn: str, intent_files: list[str], locales: list[str]=['en_US']) -> str:
"""
Creates a new bot with the specified slot type names for all the locales.
Args:
bot_name (str): The name of the bot.
role_arn (str): The ARN of the IAM role that Amazon Lex uses to access the bot.
locales (list[str], optional): The list of locales to create the bot for. Defaults to ['en_US'].
intent_files (list[str]): The list of intent files to create the bot for.
Raises:
ClientError: If the create bot request fails.
Returns:
str: The bot id.
"""
bot_id = self.create_bot(bot_name, role_arn)
bot_version = 'DRAFT'
self.create_bot_locales(bot_id, bot_version, locales)
for intent_file in intent_files:
intent = json.loads(open(intent_file).read())
self.create_intent(bot_id, bot_version, intent=intent)
self.build_bot_locales(bot_id, bot_version, locales)
def create_bot(self, bot_name: str, role_arn: str) -> str:
"""
Creates a new bot.
Args:
bot_name (str): The name of the bot.
role_arn (str): The ARN of the IAM role that Amazon Lex uses to access the bot.
Raises:
ClientError: If the create bot request fails.
Returns:
str: The bot id.
"""
self.delete_bot_if_exists(bot_name)
try:
resp = self.lex_client.create_bot(
botName=bot_name,
description='Bot for testing bot routing functionality',
roleArn=role_arn,
dataPrivacy={
'childDirected': False
},
idleSessionTTLInSeconds=300
)
self.lex_client.get_waiter('bot_available').wait(
botId=resp['botId']
)
return resp['botId']
except ClientError as e:
raise e
def create_bot_locales(self, bot_id: str, bot_version: str, locales: list[str]) -> None:
"""
Creates the specified bot locales.
Args:
bot_id (str): The ID of the bot.
bot_version (str): The version of the bot.
locale (list[str]): The locales to create.
"""
for locale in locales:
self.lex_client.create_bot_locale(
botId=bot_id,
botVersion=bot_version,
localeId=locale,
nluIntentConfidenceThreshold=0.5,
)
for locale in locales:
self.lex_client.get_waiter('bot_locale_created').wait(
botId=bot_id,
botVersion=bot_version,
localeId=locale
)
def build_bot_locales(self, bot_id: str, bot_version: str, locales: list[str]) -> None:
"""
Builds the specified bot locale.
Args:
bot_id (str): The ID of the bot.
bot_version (str): The version of the bot.
locale (list[str]): The locales to build the bot for.
"""
for locale in locales:
self.lex_client.build_bot_locale(
botId=bot_id,
botVersion=bot_version,
localeId=locale
)
for locale in locales:
self.lex_client.get_waiter('bot_locale_built').wait(
botId=bot_id,
botVersion=bot_version,
localeId=locale
)
def delete_bot_if_exists(self, bot_name: str) -> None:
"""
Deletes a specific bot if it exists.
Args:
bot_name (str): The name of the bot.
"""
bot_id = self.find_bot_id_from_bot_name(bot_name)
if bot_id:
try:
self.lex_client.delete_bot(botId=bot_id)
# wait for bot to delete
seconds_to_wait = 10
elapsed_time = 0
while self.find_bot_id_from_bot_name(bot_name) != '' and elapsed_time < seconds_to_wait:
elapsed_time += 1
if elapsed_time == seconds_to_wait:
raise RuntimeError('Bot did not delete in time')
else:
time.sleep(1)
except ClientError:
pass
def create_intent(self, bot_id: str, bot_version: str, intent: dict) -> str:
"""
Creates a new intent.
Args:
bot_id (str): The ID of the bot.
intent_name (str): The name of the intent.
locale (str): The locale of the intent.
utterances (list[str]): The list of utterances for the intent.
intent (dict): The intent object.
"""
intent['botId'] = bot_id
intent['botVersion'] = bot_version
self.lex_client.create_intent(**intent)
def find_bot_id_from_bot_name(self, bot_name: str) -> str:
"""
Finds the bot id from the bot name.
Args:
bot_name (str): The name of the bot.
Returns:
str: The bot id.
"""
bots = self.lex_client.list_bots(
filters=[
{
'name': 'BotName',
'values': [
bot_name,
],
'operator': 'EQ'
},
],
# needs to be a large number to ensure all bots are returned - filter appears to filter the returned list not the full list
maxResults=200,
)['botSummaries']
try:
return bots[0]['botId']
except IndexError:
return ''
def check_bot_exists(self, bot_name: str) -> bool:
"""
Checks if the specified bot exists.
Args:
bot_name (str): The name of the bot.
Returns:
bool: True if the bot exists, False otherwise.
"""
return self.find_bot_id_from_bot_name(bot_name) != ''
================================================
FILE: .nightswatch/functional/helpers/s3_client.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
import boto3
import json
class S3Client:
"""
A Python class to interact with Amazon S3 using Boto3.
This class provides various methods to perform operations on S3.
"""
def __init__(self, region: str) -> None:
"""
Initializes the S3Client class.
Args:
region (str): The AWS region to connect to.
Returns:
None.
Raises:
None.
"""
self.s3_client = boto3.client('s3', region_name=region)
def get_file_versions_count(self, bucket_name, file_prefix):
"""
Returns the number of versions for a given file in an S3 bucket.
Args:
bucket_name (str) name of the bucket.
file_key (str) name of the file in the bucket.
Returns:
int: The number of versions for the specified file.
"""
# Get the list of object versions for the specified file
versions = self.s3_client.list_object_versions(Bucket=bucket_name, Prefix=file_prefix)
# Count the number of versions
version_count = 0
if 'Versions' in versions:
version_count = len(versions['Versions'])
return version_count
================================================
FILE: .nightswatch/functional/helpers/translate_client.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
import boto3
import string
from botocore.exceptions import ClientError
class TranslateClient:
"""
TranslateClient is a wrapper around the AWS Translate API.
"""
def __init__(self, region: str) -> None:
"""
Initializes the TranslateClient.
:param region: The AWS region to use.
"""
self.client = boto3.client('translate', region_name=region)
def __remove_non_ascii(self, a_str: str) -> str:
"""
Removed non-printable characters from string. Needed since QnABot performs this function as well.
:param a_str: string to be cleaned
:return: cleaned string
"""
ascii_chars = set('\xa0')
def replace_unprintable_chars_with_whitespace(char):
if char in ascii_chars:
return ' '
return char
return ''.join(
map(replace_unprintable_chars_with_whitespace, a_str)
)
def list_terminologies(self) -> list[str]:
"""
Lists all the terminologies.
:return: A list of all the terminologies.
"""
# will not return all terminologies for more than 100 results but this is more than enough for now
response = self.client.list_terminologies(
MaxResults=100
)
return [terminology['Name'] for terminology in response['TerminologyPropertiesList']]
def has_terminology(self, name: str) -> bool:
"""
Returns turns true if the terminology exists.
:param name: The name of the terminology.
:return: True if the terminology exists.
"""
terminologies = self.list_terminologies()
print(name)
print(terminologies)
return name in terminologies
def delete_terminology(self, name: str):
"""
Deletes provided terminology
:param name: The terminology to delete.
:return: None.
"""
self.client.delete_terminology(
Name=name
)
def delete_all_terminologies(self):
"""
Deletes all the terminologies.
:return: None.
"""
terminologies = self.list_terminologies()
for terminology in terminologies:
self.delete_terminology(terminology)
def translate(self, text: str, target_language: str) -> str:
"""
:param text: The text to translate.
:param target_language: The target language.
:return: The translated text.
"""
source_language = 'en'
terminologies = self.list_terminologies()
response = self.client.translate_text(
Text=text,
TerminologyNames=terminologies,
SourceLanguageCode=source_language,
TargetLanguageCode=target_language,
)
return self.__remove_non_ascii(response['TranslatedText'])
================================================
FILE: .nightswatch/functional/helpers/utils/__init__.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
================================================
FILE: .nightswatch/functional/helpers/utils/textbox.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
import time
from selenium.webdriver.common.keys import Keys
class Textbox:
"""
Class representing a WebElement textbox.
This class provides methods to interact with a WebElement textbox, such as getting its value and setting a new value.
Attributes:
element (selenium.webdriver.remote.webelement.WebElement): The WebElement representing the textbox.
"""
def __init__(self, element) -> None:
"""
Initializes the Textbox with a specific WebElement.
Args:
element (selenium.webdriver.remote.webelement.WebElement): The WebElement representing the textbox.
"""
self.element = element
def __send_keys(self, keys):
"""
Private method to send specific keys to the textbox.
Args:
keys: The keys to send to the textbox.
"""
self.element.send_keys(keys)
def get_value(self) -> str:
"""
Gets the current value of the textbox.
Returns:
str: The current value of the textbox.
"""
return self.element.get_attribute("value")
def set_value(self, value):
"""
Sets a new value for the textbox.
This method first deletes the current value of the textbox, then types the new value.
Args:
value: The new value to set for the textbox.
"""
current_value = self.get_value()
if current_value != value:
length = len(current_value)
self.__send_keys(length * Keys.BACKSPACE)
self.__send_keys(value)
================================================
FILE: .nightswatch/functional/helpers/website_model/__init__.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
================================================
FILE: .nightswatch/functional/helpers/website_model/chat_page.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
import time
from selenium.webdriver.common.keys import Keys
from helpers.website_model.dom_operator import DomOperator
TEXT_INPUT_NAME = 'text-input'
MESSAGE_LIST_CSS = '.message-list'
PAGE_READINESS_ELEMENT_XPATH = '//div[@class="message-text"]'
MENU_XPATH = '//button[@aria-label="menu options"]'
LAST_MESSAGE_XPATH = '(//div[@class="message-bubble focusable message-bubble-row-bot"])[last()]'
SIGNIN_XPATH = '//form//button'
class ChatPage:
"""
Class to represent a chat page on a website.
This class uses a DomOperator object to interact with the webpage.
It includes functionality to wait for the page to load, send and receive chat messages,
check for the presence of elements, and select a language locale from a menu.
:param operator: The DomOperator object to operate on the webpage.
"""
def __init__(self, operator: DomOperator) -> None:
"""
Initialize ChatPage with a DomOperator object and signs in as current user if bot is configured to be private.
:param operator: The DomOperator object to operate on the webpage.
"""
self.operator = operator
if self.operator.get_title() != 'QnABot Client':
self.operator.select_xpath(SIGNIN_XPATH, wait=5, click=True)
self.__wait_to_load()
def __wait_to_load(self):
"""
Private method to wait for the page to load by waiting for the presence of a specific element.
"""
self.operator.wait_for_element_by_xpath(PAGE_READINESS_ELEMENT_XPATH)
def __wait_for_message_response(self, message):
"""
Private method to wait for a response to the given message.
:param message: The message to wait for a response to.
"""
self.operator.wait_for_element_by_xpath(f'(//div[normalize-space(text()) = "{message}"]/ancestor::div[contains(concat(" ", @class, " "), " message-human ")][1])[last()]/following-sibling::div[@class="v-row message message-bot"]', delay=30)
def select_text_input(self):
"""
Select the text input element on the chat page.
:return: The selected text input element.
"""
return self.operator.select_name(TEXT_INPUT_NAME)
def send_message(self, message):
"""
Send a message through the text input on the chat page and wait for a response.
:param message: The message to send.
"""
text_input = self.select_text_input()
text_input.send_keys(message)
text_input.send_keys(Keys.ENTER)
self.__wait_for_message_response(message)
def get_messages(self) -> str:
"""
Get the text of all messages in the chat.
:return: The text of all messages in the chat.
"""
full_page = self.operator.select_css(MESSAGE_LIST_CSS)
return full_page.text
def get_last_message_element(self):
"""
Get the last message element in the chat.
:return: last message element.
"""
return self.operator.select_xpath(LAST_MESSAGE_XPATH)
def get_last_message_text(self) -> str:
"""
Get the last message text in the chat.
:return: the text content in the last message element.
"""
return self.get_last_message_element().text
def has_element_with_xpath(self, xpath) -> str:
"""
Check if an element with the given XPath exists in the chat page.
:param xpath: The XPath of the element.
:return: True if the element exists, False otherwise.
"""
return self.operator.element_exists_by_xpath(xpath)
def select_locale(self, locale: str):
"""
Select the given locale from the menu and wait for the locale info element to update.
:param locale: The locale to select.
"""
self.operator.select_xpath(MENU_XPATH, click=True)
self.operator.wait_for_element_by_xpath(f'//div[@class="v-list-item-title" and normalize-space(text()) = "{locale}"]')
self.operator.select_xpath(f'//div[@class="v-list-item-title" and normalize-space(text()) = "{locale}"]', click=True)
self.operator.wait_for_element_by_xpath(f'//span[@class="localeInfo" and contains(text(), "{locale}")]')
def send_positive_feedback(self):
"""
Send positive feedback through the chat page.
"""
self.operator.select_xpath('//i[contains(@class, "feedback-icons-positive")]', click=True)
self.__wait_for_message_response('Thumbs up')
================================================
FILE: .nightswatch/functional/helpers/website_model/custom_terminology_page.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
from helpers.website_model.dom_operator import DomOperator
UPLOAD_FILE_ID = 'upload-file'
class CustomTerminologyPage:
"""
Class to represent a Custom Terminology page on a website.
This class uses a DomOperator object to interact with the webpage.
It includes functionality to upload a file which contains custom terminology that should not be translated into different languages.
:param operator: The DomOperator object to operate on the webpage.
"""
def __init__(self, operator: DomOperator) -> None:
"""
Initialize CustomTerminologyPage with a DomOperator object.
:param operator: The DomOperator object to operate on the webpage.
"""
self.operator = operator
def upload_file(self, file):
"""
Upload a file to the Custom Terminology page.
:param file: The path to the file to be uploaded.
"""
self.operator.select_id(UPLOAD_FILE_ID).send_keys(file)
================================================
FILE: .nightswatch/functional/helpers/website_model/dom_operator.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
import os
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException
DOWNLOAD_DIR = f'../../{os.path.realpath(os.path.dirname(__file__))}/files'
HEADLESS_MODE_ENABLED = os.environ.get('HEADLESS_BROWSER') != 'false'
class DomOperator():
"""
A singleton class to interact with the Document Object Model (DOM) of a webpage using Selenium.
This class provides various methods for interacting with webpage elements,
including selecting, checking existence, waiting for elements, and manipulating browser behavior.
"""
def __new__(cls):
"""
Implement the singleton pattern. If an instance of this class exists, it's returned.
Otherwise, a new instance is created and returned.
"""
if not hasattr(cls, 'instance'):
cls.instance = super(DomOperator, cls).__new__(cls)
return cls.instance
def __init__(self) -> None:
"""
Initialize the class with a Selenium webdriver with specific download preferences.
"""
options = Options()
if HEADLESS_MODE_ENABLED:
options.add_argument("-headless")
options.set_preference("browser.download.folderList", 2)
options.set_preference("browser.download.manager.showWhenStarting", False)
options.set_preference("browser.download.dir", DOWNLOAD_DIR)
options.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/x-gzip")
options.set_preference("devtools.console.stdout.content", True)
service = Service(log_output="../test_browser_console.log")
self.driver = webdriver.Firefox(options=options, service=service)
self.driver.implicitly_wait(5)
def get_url(self, url):
"""
Navigate the webdriver to the provided URL.
:param url: The URL to navigate to.
"""
self.driver.get(url)
def get_current_url(self) -> str:
"""
Get the current URL that the webdriver is on.
:return: The current URL as a string.
"""
return self.driver.current_url
def set_window_size(self, x, y):
"""
Set the size of the browser window.
:param x: The width of the window.
:param y: The height of the window.
"""
self.driver.set_window_size(x, y)
def get_title(self) -> str:
"""
Get the title of the current webpage.
:return: The title of the current webpage as a string.
"""
return self.driver.title
def refresh_browser(self) -> None:
"""
Refresh the current webpage.
"""
self.driver.refresh()
def element_exists_by_id(self, id, wait:int=5) -> bool:
"""
Check if an element with the given ID exists in the webpage.
:param id: The ID of the element.
:return: True if the element exists, False otherwise.
"""
try:
WebDriverWait(self.driver, wait).until(EC.presence_of_element_located((By.ID, id)))
return True
except TimeoutException:
print(f"Timeout exeception waiting for element with id {id} to appear")
return False
except NoSuchElementException:
return False
def element_exists_by_xpath(self, xpath, wait:int=3) -> bool:
"""
Check if an element with the given XPath exists in the webpage.
:param xpath: The XPath of the element.
:return: True if the element exists, False otherwise.
"""
try:
WebDriverWait(self.driver, wait).until(EC.presence_of_element_located((By.XPATH, xpath)))
return True
except TimeoutException:
print(f"Timeout exeception waiting for element with xpath {xpath} to appear")
return False
except NoSuchElementException:
return False
def select_id(self, id: str, wait:int=3, click:bool=False):
"""
Select the element with the given ID and optionally click on it.
:param id: The ID of the element.
:param wait: The time in seconds to implicitly wait for the element.
:param click: Whether to click the element or not.
:return: The selected element.
"""
try:
element = self.driver.find_element(By.ID, id)
if click:
WebDriverWait(self.driver, wait).until(EC.element_to_be_clickable((By.ID, id)))
self.driver.execute_script("arguments[0].click();", element)
return element
except NoSuchElementException as e:
raise RuntimeError(f'Element with ID {id} not found.')
def click_element_by_id(self, id: str, wait:int=0):
"""
Click on the element with the given ID
:param id: The ID of the element.
:param wait: The time in seconds to implicitly wait for the element.
"""
try:
element = self.driver.find_element(By.ID, id)
self.driver.execute_script("arguments[0].click();", element)
except NoSuchElementException as e:
raise RuntimeError(f'Element with ID {id} not found.')
def select_css(self, css_selector: str, wait:int=0, click:bool=False):
"""
Select the element with the given CSS selector and optionally click on it.
:param css_selector: The CSS selector of the element.
:param wait: The time to implicitly wait for the element.
:param click: Whether to click the element or not.
:return: The selected element.
"""
try:
element = self.driver.find_element(By.CSS_SELECTOR, (css_selector))
if click:
element.click()
return element
except NoSuchElementException as e:
raise RuntimeError(f'Element with CSS selector {css_selector} not found.')
def select_name(self, name: str, wait:int=0, click:bool=False):
"""
Select the element with the given name and optionally click on it.
:param name: The name of the element.
:param wait: The time to implicitly wait for the element.
:param click: Whether to click the element or not.
:return: The selected element.
"""
try:
element = self.driver.find_element(By.NAME, (name))
if click:
self.driver.execute_script("arguments[0].click();", element)
return element
except NoSuchElementException as e:
raise RuntimeError(f'Element with name {name} not found.')
def select_xpath(self, xpath: str, wait:int=0, click:bool=False):
"""
Select the element with the given XPath and optionally click on it.
:param xpath: The XPath of the element.
:param wait: The time to implicitly wait for the element.
:param click: Whether to click the element or not.
:return: The selected element.
"""
try:
element = self.driver.find_element(By.XPATH, xpath)
if click:
self.driver.execute_script("arguments[0].click();", element)
return element
except NoSuchElementException as e:
raise RuntimeError(f'Element with XPath {xpath} not found.')
def wait_for_element_attribute(self, id: str, attribute: str, value: str, delay: int = 10):
"""
Wait for the element with the given ID to have the given attribute with the given value.
:param id: The ID of the element.
:param attribute: The name of the attribute.
:param value: The value of the attribute.
:param delay: The maximum time in seconds to wait for the element.
:return: The element if it appears within the wait time, None otherwise.
"""
try:
return WebDriverWait(self.driver, delay).until(EC.text_to_be_present_in_element_attribute((By.ID, id), attribute, value))
except TimeoutException:
print(f'TimeoutException: element id: "{id}" waited {delay}s to load.')
def wait_for_element_by_id(self, id: str, delay: int = 10):
"""
Wait for the element with the given ID to be present in the webpage.
:param id: The ID of the element.
:param delay: The maximum time in seconds to wait for the element.
:return: The element if it appears within the wait time, None otherwise.
"""
try:
return WebDriverWait(self.driver, delay).until(EC.presence_of_element_located((By.ID, id)))
except TimeoutException:
print(f'TimeoutException: element id: "{id}" waited {delay}s to load.')
def wait_for_element_by_xpath(self, xpath: str, delay: int = 10):
"""
Wait for the element with the given XPath to be present in the webpage.
:param xpath: The XPath of the element.
:param delay: The maximum time to wait for the element.
:return: The element if it appears within the wait time, None otherwise.
"""
try:
return WebDriverWait(self.driver, delay).until(EC.presence_of_element_located((By.XPATH, xpath)))
except TimeoutException:
print(f'TimeoutException: element xpath: "{xpath}" waited {delay}s to load.')
def wait_for_element_by_id_text(self, id: str, text: str, delay: int = 10):
"""
Wait for the element with the given ID and text to be present in the webpage.
:param id: The ID of the element.
:param text: The text expected to be present in the element.
:param delay: The maximum time to wait for the element.
:return: True if the element with the expected text appears within the wait time, False otherwise.
"""
try:
return WebDriverWait(self.driver, delay).until(EC.text_to_be_present_in_element((By.ID, id), text))
except TimeoutException:
print(f'TimeoutException: element id "{id}" with text: "{text}" waited {delay}s to load.')
def wait_for_element_by_xpath_text(self, xpath: str, text: str, delay: int = 10):
"""
Wait for the element with the given xpath and text to be present in the webpage.
:param xpath: The xpath of the element.
:param text: The text expected to be present in the element.
:param delay: The maximum time to wait for the element.
:return: True if the element with the expected text appears within the wait time, False otherwise.
"""
try:
return WebDriverWait(self.driver, delay).until(EC.text_to_be_present_in_element((By.XPATH, xpath), text))
except TimeoutException:
print(f'TimeoutException: element id "{xpath}" with text: "{text}" waited {delay}s to load.')
def switch_windows(self):
"""
Switch to the next window handle if there is more than one window handle present.
"""
if len(self.driver.window_handles) == 1:
return
original_window = self.driver.current_window_handle
for window_handle in self.driver.window_handles:
if window_handle != original_window:
self.driver.switch_to.window(window_handle)
break
def end_session(self):
"""
End the webdriver session.
:return: The result of the webdriver's quit function.
"""
return self.driver.quit()
================================================
FILE: .nightswatch/functional/helpers/website_model/edit_page.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
import time
import logging
import random
import string
from helpers.website_model.dom_operator import DomOperator
from helpers.utils.textbox import Textbox
from selenium.webdriver.remote.webelement import WebElement
MODAL_XPATH = '//div[@id="add-question-form"]'
EDIT_MODAL_XPATH = '//div[@class="dialog dialog--active"]'
SUB_MENU_ID = 'edit-sub-menu'
ADD_QUESTION_ID = 'add-question-btn'
REFRESH_BUTTON_XPATH = '//button//span[contains(string(), "Refresh")]'
ITEM_ID = 'qid'
QUESTION_ID = 'qna-q'
ANSWER_ID = 'qna-a'
DESCRIPTION_ID = 'slottype-descr'
MARKDOWN_ANSWER_ID = 'qna-alt-markdown'
QNA_RADIO_XPATH = '//input[@type="radio" and @value="qna"]'
QUESTION_ADVANCED_MENU_XPATH = '//button[@class="v-expansion-panel-title" and contains(string(), "Advanced")]'
QUESTION_TOPIC_ID = 't'
QUESTION_CARD_TITLE_ID = 'r-title'
QUESTION_CARD_SUBTITLE_ID = 'r-subTitle'
QUESTION_CARD_URL_ID = 'r-imageUrl'
QUESTION_CARD_ADD_LEX_BUTTON_ID = 'qna.r.buttons-add'
ADD_SA_BUTTON_ID = 'qna.sa-add'
LAMBDA_HOOK_ID = 'l'
LAMBDA_HOOK_ARGS_ID_QNA = 'qna-args'
LAMBDA_HOOK_ARGS_ID = 'args'
CLIENT_FILTER_ID = 'clientFilterValues'
REF_MARKDOWN_ID = 'text-refMarkdown'
TAGS_ID = 'tags'
RP_ID = 'rp'
NEXT_ID = 'next'
BOT_ROUTING_ID = 'qna-botRouting-specialty_bot'
BOT_ROUTING_NAME_ID = 'qna-botRouting-specialty_bot_name'
BOT_ROUTING_ATTRIBUTE_ID = 'qna-botRouting-specialty_bot_session_attributes_to_merge'
KENDRA_REDIRECT_QUERY_ID = 'kendraRedirectQueryText'
KENDRA_REDIRECT_QUERY_ARGS_ID = 'kendraRedirectQueryArgs'
KENDRA_CONFIDENCE_ID = 'kendraRedirectQueryConfidenceThreshold'
CHAINING_ID = 'conditionalChaining'
RESPONSE_HOOK_ID = 'qna-elicitResponse-responsebot_hook'
RESPONSE_ATTRIBUTE_ID = 'qna-elicitResponse-response_sessionattr_namespace'
QUESTION_SUBMIT_ID = 'add-question-submit'
QUESTION_CANCEL_ID = 'add-question-cancel'
ADD_UTTERANCE_ID = 'qna.q-add'
ADD_QUESTION_SUCCESS_ID = 'add-success'
ADD_QUESTION_CLOSE_ID = 'add-close'
# EDIT_QUESTION_SUBMIT_ID = 'edit-submit'
# Cannot use ID due to hidden modals with buttons using same ID
EDIT_QUESTION_SUBMIT_XPATH = EDIT_MODAL_XPATH + '//button[@id="edit-submit"]'
EDIT_QUESTION_SUBMIT_ID = "edit-submit"
EDIT_QUESTION_ADVANCED_MENU_XPATH = '//button[@class="v-expansion-panel-title" and contains(string(), "Advanced")]'
EDIT_QUESTION_CANCEL_ID = 'edit-cancel'
EDIT_QUESTION_SUCCESS_ID = 'edit-success'
EDIT_QUESTION_CLOSE_ID = 'edit-close'
QUIZ_RADIO_XPATH = '//input[@type="radio" and @value="quiz"]'
QUIZ_QUESTION_ID = 'quiz-question'
QUIZ_CORRECT_ANSWER_ID = 'quiz-correctAnswers'
QUIZ_INCORRECT_ANSWER_ID = 'quiz-incorrectAnswers'
QUIZ_ADD_CORRECT_ANSWER_BUTTON_ID = 'quiz.correctAnswers-add'
QUIZ_ADD_INCORRECT_ANSWER_BUTTON_ID = 'quiz.incorrectAnswers-add'
SLOT_RADIO_XPATH = '//input[@type="radio" and @value="slottype"]'
SLOT_TYPE_DESCRIPTION_XPATH = MODAL_XPATH + '//input[@id="slottype-descr"]'
SLOT_TYPE_RESTRICT_VALUES_XPATH = MODAL_XPATH + '//div[@data-path="slottype.resolutionStrategyRestrict"]//input'
SLOT_TYPE_ADD_BUTTON_XPATH = MODAL_XPATH + '//button[@id="slottype.slotTypeValues-add"]'
SLOT_DEDICATED_BOT_CHECKBOX_XPATH = MODAL_XPATH + '//div[@data-path="qna.enableQidIntent"]//input'
SLOT_ADD_SLOT_BUTTON_ID = MODAL_XPATH + '//button[@id="qna.slots-add"]'
TEXT_RADIO_XPATH = '//input[@type="radio" and @value="text"]'
PASSAGE_ID = 'text-passage'
# CONFIRM_DELETE_ID = 'confirm-delete'
# Cannot use ID due to hidden delete buttons sharing same id
CONFIRM_DELETE_XPATH = '//div[@class="v-card-actions"]//button[@id="confirm-delete"]'
CONFIRM_DELETE_CLOSE_XPATH = '//div[@class="v-card-actions"]//button//span[contains(string(), "close")]'
CONFIRM_DELETE_SUCCESS_ID = 'delete-success'
REBUILD_LEX_ID = 'lex-rebuild'
REBUILD_LEX_LOADING_ID = 'lex-loading'
REBUILD_LEX_SUCCESS_ID = 'lex-success'
REBUILD_LEX_CLOSE_ID = 'lex-close'
SYNC_KENDRA_FAQ_ID = 'kendra-sync'
SYNC_KENDRA_STATUS_ID = 'kendra-syncing'
SYNC_KENDRA_SUCCESS_ID = 'success'
SYNC_KENDRA_CLOSE_ID = 'kendra-close'
TEST_TAB_XPATH = '//button[@id="test-tab"]'
TEST_ALL_TAB_XPATH = '//button[@id="testAll-tab"]'
TEST_TAB_QUERY_ID = 'query'
TEST_TAB_QUERY_BUTTON_ID = 'query-test'
TEST_ALL_BUTTON_ID = 'testAll'
TEST_ALL_JOBS_ID = 'test-jobs'
# arbitrary element to wait for; one of the last elements to always load
# need to wait for table to fully load, otherwise auth error thrown on page exit
# if there are no elements in the table then we wait for the timeout, which will throw a warning
PAGE_READINESS_ELEMENT_XPATH = '//table//td//div'
class EditPage:
"""
A class representing the administrative page that is used for managing questions and answers for Q&A Bot.
This page provides functionality to create, update, and delete 3 types of questions: QnA, SlotType, and Quiz.
Additionally, it has a submenu that triggers the AWS Lex chatbot to rebuild with any updates to the questions
and provides functionality to sync AWS Kendra FAQ based on the questions.
Attributes
----------
operator: DomOperator
A DomOperator object used to interact with the web page.
"""
def __init__(self, operator: DomOperator) -> None:
"""
Initializes EditPage with the provided DomOperator object.
Parameters
----------
operator : DomOperator
A DomOperator object used to interact with the web page.
"""
self.operator = operator
self.__wait_to_load()
def __wait_to_load(self):
"""
A private method to wait for a page to load. Waits for a specific element
identified by its ID.
"""
self.operator.wait_for_element_by_xpath(PAGE_READINESS_ELEMENT_XPATH)
time.sleep(1)
def refresh_questions(self):
"""
Refreshes the question table.
"""
time.sleep(3)
self.operator.wait_for_element_by_xpath(REFRESH_BUTTON_XPATH)
self.operator.select_xpath(REFRESH_BUTTON_XPATH, click=True)
time.sleep(3)
def add_question(self, qid: str, type: str, q: list[str]=[], a: str='', descr: str='', _id: str='', l: str='', args: str='', elicitResponse: dict={}, slots: list[dict]=[], r: dict={}, t: str='', question: str='', questions: list[str]=[], correctAnswers: list[str]=[], incorrectAnswers: list[str]=[], slotTypeValues: list[dict]=[], resolutionStrategyRestrict: bool=False, enableQidIntent: bool=False, kendraRedirectQueryText: str='', kendraRedirectQueryConfidenceThreshold: str='', conditionalChaining: str='', sa: list[dict]=[], botRouting: dict={}, passage: str='', alt: dict={}):
"""
Adds a new question to the bot. The method behavior depends on the type
of question being added ('quiz', 'slottype', or "qna"). After adding the question,
it waits for confirmation of the successful addition.
"""
self.operator.click_element_by_id(ADD_QUESTION_ID, wait=10)
self.operator.wait_for_element_by_xpath(QUESTION_ADVANCED_MENU_XPATH)
self.operator.select_xpath(QUESTION_ADVANCED_MENU_XPATH, click=True)
if type == 'quiz':
self.__add_quiz_question(question, correctAnswers, incorrectAnswers)
elif type == 'slottype':
self.__add_slot_question(descr, slotTypeValues, resolutionStrategyRestrict)
elif type == 'text':
self.__add_text_question(passage)
else:
self.__add_qna_question(q, a, l, args, slots, r, t, elicitResponse, kendraRedirectQueryText, kendraRedirectQueryConfidenceThreshold, conditionalChaining, sa, botRouting, alt)
qid_textbox = Textbox(self.operator.select_id(f"{type}-{ITEM_ID}"))
qid_textbox.set_value(qid)
self.operator.click_element_by_id(QUESTION_SUBMIT_ID)
self.operator.wait_for_element_by_id(ADD_QUESTION_SUCCESS_ID, delay=30)
self.operator.select_id(ADD_QUESTION_CLOSE_ID, wait= 5, click=True)
self.operator.wait_for_element_by_id(ADD_QUESTION_ID)
def __add_qna_lambda_hook(self, l, l_args):
"""
A private method that sets a lambda hook for a QnA question. This lambda hook
can be used to provide dynamic responses.
"""
l_textbox = Textbox(self.operator.select_id(f"qna-{LAMBDA_HOOK_ID}"))
l_textbox.set_value(l)
la_textbox = Textbox(self.operator.select_id(f"{LAMBDA_HOOK_ARGS_ID_QNA}-0"))
la_textbox.set_value(l_args)
def __add_qna_slot(self, index, slot):
"""
A private method that adds a slot to a QnA question. Slots can be used to capture
and utilize user inputs within the conversation.
"""
if 'slotRequired' in slot:
self.operator.select_xpath(f'{MODAL_XPATH}//div[@data-path="qna.slots[{index}].slotRequired"]//input', click=slot['slotRequired'])
if 'slotCached' in slot:
self.operator.select_xpath(f'{MODAL_XPATH}//div[@data-path="qna.slots[{index}].slotValueCached"]//i', click=slot['slotCached'])
name_textbox = Textbox(self.operator.select_xpath(f'{MODAL_XPATH}//div[@data-path="qna.slots[{index}].slotName"]//input'))
name_textbox.set_value(slot['slotName'])
type_textbox = Textbox(self.operator.select_xpath(f'{MODAL_XPATH}//div[@data-path="qna.slots[{index}].slotType"]//input'))
type_textbox.set_value(slot['slotType'])
prompt_textbox = Textbox(self.operator.select_xpath(f'{MODAL_XPATH}//div[@data-path="qna.slots[{index}].slotPrompt"]//input'))
prompt_textbox.set_value(slot['slotPrompt'])
if 'slotSampleUtterances' in slot:
utterances_textbox = Textbox(self.operator.select_xpath(f'{MODAL_XPATH}//div[@data-path="qna.slots[{index}].slotSampleUtterances"]//input'))
utterances_textbox.set_value(slot['slotSampleUtterances'])
def __add_qna_card(self, r, type: str='qna'):
"""
A private method that sets up a response card for a QnA question. Response cards
provide additional visual elements for the bot.
"""
title_textbox = Textbox(self.operator.select_id(f'{type}-{QUESTION_CARD_TITLE_ID}'))
title_textbox.set_value(r['title'])
subtitle_textbox = Textbox(self.operator.select_id(f'{type}-{QUESTION_CARD_SUBTITLE_ID}'))
subtitle_textbox.set_value(r['subTitle'])
url_textbox = Textbox(self.operator.select_id(f'{type}-{QUESTION_CARD_URL_ID}'))
url_textbox.set_value(r['imageUrl'])
for index, button in enumerate(r['buttons']):
if index > 0:
self.operator.select_id(QUESTION_CARD_ADD_LEX_BUTTON_ID, click=True)
button_display_textbox = Textbox(self.operator.select_xpath(f'//div[@data-path="qna.r.buttons[{index}].text"]//input'))
button_display_textbox.set_value(button['text'])
button_value_textbox = Textbox(self.operator.select_xpath(f'//div[@data-path="qna.r.buttons[{index}].value"]//input'))
button_value_textbox.set_value(button['value'])
def __add_qna_question(self, q: list[str], a: str, l: str='', args: str='', slots: list[dict]=[], r: dict={}, t: str='', elicitResponse: dict={}, kendraRedirectQueryText: str='', kendraRedirectQueryConfidenceThreshold: str='', conditionalChaining: str='', sa: list[dict]=[], botRouting: dict={}, alt: dict={}, mode: str= 'add'):
"""
A private method that adds a QnA question to the bot.
"""
type = "qna"
if mode == 'add':
self.operator.select_xpath(QNA_RADIO_XPATH, click=True)
for index, utterance in enumerate(q):
utterance_id = f'{QUESTION_ID}-{index}'
# if not self.operator.element_exists_by_id(utterance_id):
if index > 0:
self.operator.click_element_by_id(ADD_UTTERANCE_ID)
utterance_textbox = Textbox(self.operator.select_id(utterance_id))
utterance_textbox.set_value(utterance)
a_textbox = Textbox(self.operator.select_id(ANSWER_ID))
a_textbox.set_value(a)
if alt:
alt_textbox = Textbox(self.operator.select_id(MARKDOWN_ANSWER_ID))
alt_textbox.set_value(alt['markdown'])
if l:
self.__add_qna_lambda_hook(l, args)
if slots:
self.operator.select_xpath(SLOT_DEDICATED_BOT_CHECKBOX_XPATH, click=True)
for index, slot in enumerate(slots):
if index > 0:
self.operator.select_xpath(SLOT_ADD_SLOT_BUTTON_ID, click=True)
self.__add_qna_slot(index, slot)
if r:
self.__add_qna_card(r, 'qna')
if t:
topic_textbox = Textbox(self.operator.select_id(f'{type}-{QUESTION_TOPIC_ID}'))
topic_textbox.set_value(t)
if elicitResponse:
hook_textbox = Textbox(self.operator.select_id(RESPONSE_HOOK_ID))
hook_textbox.set_value(elicitResponse['responsebot_hook'])
hook_textbox = Textbox(self.operator.select_id(RESPONSE_ATTRIBUTE_ID))
hook_textbox.set_value(elicitResponse['response_sessionattr_namespace'])
if kendraRedirectQueryText:
kendra_query_textbox = Textbox(self.operator.select_id(f'{type}-{KENDRA_REDIRECT_QUERY_ID}'))
kendra_query_textbox.set_value(kendraRedirectQueryText)
kendra_confidence_textbox = Textbox(self.operator.select_id(f'{type}-{KENDRA_CONFIDENCE_ID}'))
kendra_confidence_textbox.set_value(kendraRedirectQueryConfidenceThreshold)
if conditionalChaining:
chaining_textbox = Textbox(self.operator.select_id(f'{type}-{CHAINING_ID}'))
chaining_textbox.set_value(conditionalChaining)
for index, attribute in enumerate(sa):
if index > 0:
self.operator.select_xpath(ADD_SA_BUTTON_ID, click=True)
sa_name_textbox = Textbox(self.operator.select_xpath(f'//div[@data-path="{type}.sa[{index}].text"]//input'))
sa_name_textbox.set_value(attribute['text'])
sa_value_textbox = Textbox(self.operator.select_xpath(f'//div[@data-path="{type}.sa[{index}].value"]//textarea'))
sa_value_textbox.set_value(attribute['value'])
if botRouting:
for key, value in botRouting.items():
if self.operator.element_exists_by_id(f"{type}-botRouting-{key}"):
bot_routing_textbox = Textbox(self.operator.select_id(f"{type}-botRouting-{key}"))
bot_routing_textbox.set_value(value)
def __add_quiz_question(self, question: str, correctAnswers: list[str]=[], incorrectAnswers: list[str]=[]):
"""
A private method that adds a quiz question to the bot. Quiz questions provide multiple
answers and the bot verifies if the user's answer is correct.
"""
self.operator.select_xpath(QUIZ_RADIO_XPATH, click=True)
q_textbox = Textbox(self.operator.select_id(QUIZ_QUESTION_ID))
q_textbox.set_value(question)
for index, answer in enumerate(correctAnswers):
answer_id = QUIZ_CORRECT_ANSWER_ID
answer_id = answer_id + f'-{index}'
self.operator.select_id(QUIZ_ADD_CORRECT_ANSWER_BUTTON_ID, wait=5, click=True)
a_textbox = Textbox(self.operator.select_id(answer_id))
a_textbox.set_value(answer)
for index, answer in enumerate(incorrectAnswers):
answer_id = QUIZ_INCORRECT_ANSWER_ID
answer_id = answer_id + f'-{index}'
self.operator.select_id(QUIZ_ADD_INCORRECT_ANSWER_BUTTON_ID, click=True)
a_textbox = Textbox(self.operator.select_id(answer_id))
a_textbox.set_value(answer)
def __add_slot_question(self, descr: str='', slotTypeValues: list[dict]=[], resolutionStrategyRestrict: bool=False):
"""
A private method that adds a slot type question to the bot. Slot type questions can
capture user inputs as slot values for use in the conversation.
"""
self.operator.select_xpath(SLOT_RADIO_XPATH, click=True)
description_textbox = Textbox(self.operator.select_xpath(SLOT_TYPE_DESCRIPTION_XPATH))
description_textbox.set_value(descr)
self.operator.select_xpath(SLOT_TYPE_RESTRICT_VALUES_XPATH, click=resolutionStrategyRestrict)
for index, values in enumerate(slotTypeValues):
if index > 0:
self.operator.select_xpath(SLOT_TYPE_ADD_BUTTON_XPATH, click=True)
value_textbox = Textbox(self.operator.select_xpath(f'//div[@data-path="slottype.slotTypeValues[{index}].samplevalue"]//input', wait=5))
value_textbox.set_value(values['samplevalue'])
synonym_textbox = Textbox(self.operator.select_xpath(f'//div[@data-path="slottype.slotTypeValues[{index}].synonyms"]//input', wait=5))
synonym_textbox.set_value(values['synonyms'])
def __add_text_question(self, passage):
"""
A private method that adds a text type question to the bot. Text type questions capture passages used for LLM inference.
"""
self.operator.select_xpath(TEXT_RADIO_XPATH, click=True)
passage_textbox = Textbox(self.operator.select_id(PASSAGE_ID))
passage_textbox.set_value(passage)
def check_question_exists_by_qid(self, qid: str) -> bool:
"""
Checks if a question exists by its QID. Returns True if the question exists,
False otherwise.
"""
return self.operator.element_exists_by_id(f'qa-{qid}')
def edit_question_by_qid(self, qid: str, type: str, q: list[str]=[], a: str='', descr: str='', _id: str='', l: str='', args: str='', elicitResponse: dict={}, slots: list[dict]=[], r: dict={}, t: str='', question: str='', questions: list[str]=[], correctAnswers: list[str]=[], incorrectAnswers: list[str]=[], slotTypeValues: list[dict]=[], resolutionStrategyRestrict: bool=False, enableQidIntent: bool=False, kendraRedirectQueryText: str='', kendraRedirectQueryConfidenceThreshold: str='', conditionalChaining: str='', passage: str='', alt: dict={}):
"""
Edits an existing question identified by its QID. The type of edit performed
depends on the type of question ('quiz', 'slottype', or "qna").
"""
logging.info(f"Editing question : {qid}, type : {type}")
self.operator.select_xpath(f'//span[@id="qa-{qid}-edit"]//descendant::button', wait=1, click=True)
self.operator.wait_for_element_by_xpath(EDIT_QUESTION_ADVANCED_MENU_XPATH)
self.operator.select_xpath(EDIT_QUESTION_ADVANCED_MENU_XPATH, click=True)
if type == 'quiz':
self.__add_quiz_question(question, correctAnswers, incorrectAnswers)
elif type == 'slottype':
self.__add_slot_question(descr, slotTypeValues, resolutionStrategyRestrict)
elif type == 'text':
self.__add_text_question(passage)
else:
self.__add_qna_question(q, a, l, args, slots, r, t, elicitResponse, kendraRedirectQueryText, kendraRedirectQueryConfidenceThreshold, conditionalChaining, alt, mode='edit')
self.operator.wait_for_element_by_id(EDIT_QUESTION_SUBMIT_ID)
self.operator.click_element_by_id(EDIT_QUESTION_SUBMIT_ID)
self.operator.wait_for_element_by_id(EDIT_QUESTION_SUCCESS_ID)
self.operator.click_element_by_id(EDIT_QUESTION_CLOSE_ID, wait= 10)
self.operator.wait_for_element_by_id(ADD_QUESTION_ID)
def match_question_field_values(
self,
qid: str,
type: str='',
q: list[str]=[],
a: str='',
descr: str='',
_id: str='',
l: str='',
args: str='',
elicitResponse: dict={},
slots: list[dict]=[],
r: dict={},
t: str='',
slotTypeValues: list[dict]=[],
resolutionStrategyRestrict: bool=False,
enableQidIntent: bool=False,
kendraRedirectQueryText: str='',
kendraRedirectQueryConfidenceThreshold: str='',
conditionalChaining: str='',
sa: list[dict]=[],
botRouting: dict={},
passage: str='',
alt: dict={},
clientFilterValues: str='',
refMarkdown: str='',
tags: str='',
kendraRedirectQueryArgs: list[str]=[],
rp: str='',
next: str='',
) -> bool:
self.operator.wait_for_element_by_xpath(f'//span[@id="qa-{qid}-edit"]//descendant::button')
self.operator.select_xpath(f'//span[@id="qa-{qid}-edit"]//descendant::button', click=True)
self.operator.wait_for_element_by_xpath(EDIT_QUESTION_ADVANCED_MENU_XPATH)
self.operator.select_xpath(EDIT_QUESTION_ADVANCED_MENU_XPATH, click=True)
for index, utterance in enumerate(q):
utterance_id = f'{QUESTION_ID}-{index}'
utterance_textbox = Textbox(self.operator.select_id(utterance_id))
if utterance_textbox.get_value() != utterance:
print(f'Value "{utterance_textbox.get_value()}" does not match expected field value "{utterance=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if a:
a_textbox = Textbox(self.operator.select_id(ANSWER_ID))
if a_textbox.get_value() != a:
print(f'Value "{a_textbox.get_value()}" does not match expected field value "{a=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if alt:
alt_textbox = Textbox(self.operator.select_id(MARKDOWN_ANSWER_ID))
if alt_textbox.get_value() != alt['markdown']:
print(f'Value "{alt_textbox.get_value()}" does not match expected field value "{alt=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if descr:
descr_textbox = Textbox(self.operator.select_id(DESCRIPTION_ID))
if descr_textbox.get_value() != descr:
print(f'Value "{descr_textbox.get_value()}" does not match expected field value "{descr=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if l:
l_textbox = Textbox(self.operator.select_id(f"{type}-{LAMBDA_HOOK_ID}"))
if l_textbox.get_value() != l:
print(f'Value "{l_textbox.get_value()}" does not match expected field value "{l=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
for index, l_arg in enumerate(args):
l_arg_id = f'{type}-{LAMBDA_HOOK_ARGS_ID}-{index}'
arg_textbox = Textbox(self.operator.select_id(l_arg_id))
if arg_textbox.get_value() != l_arg:
print(f'Value "{arg_textbox.get_value()}" does not match expected field value "{l_arg=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if r:
title_textbox = Textbox(self.operator.select_id(f'{type}-{QUESTION_CARD_TITLE_ID}'))
if title_textbox.get_value() != r['title']:
print(f'Value "{title_textbox.get_value()}" does not match expected field value "{r=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if 'subTitle' in r:
subtitle_textbox = Textbox(self.operator.select_id(f'{type}-{QUESTION_CARD_SUBTITLE_ID}'))
if subtitle_textbox.get_value() != r['subTitle']:
print(f'Value "{subtitle_textbox.get_value()}" does not match expected field value "{r=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
url_textbox = Textbox(self.operator.select_id(f'{type}-{QUESTION_CARD_URL_ID}'))
if url_textbox.get_value() != r['imageUrl']:
print(f'Value "{url_textbox.get_value()}" does not match expected field value "{r=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
for index, button in enumerate(r['buttons']):
button_display_textbox = Textbox(self.operator.select_xpath(f'//div[@data-path="{type}.r.buttons[{index}].text"]//input[@id="{type}-r-buttons-{index}-text"]'))
if button_display_textbox.get_value() != button['text']:
print(f'Value "{button_display_textbox.get_value()}" does not match expected field value "{button=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
button_value_textbox = Textbox(self.operator.select_xpath(f'//div[@data-path="{type}.r.buttons[{index}].value"]//input[@id="{type}-r-buttons-{index}-value"]'))
if button_value_textbox.get_value() != button['value']:
print(f'Value "{button_value_textbox.get_value()}" does not match expected field value "{button=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if t:
topic_textbox = Textbox(self.operator.select_id(f'{type}-{QUESTION_TOPIC_ID}'))
if topic_textbox.get_value() != t:
print(f'Value "{topic_textbox.get_value()}" does not match expected field value "{t=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if elicitResponse:
hook_textbox = Textbox(self.operator.select_id(RESPONSE_HOOK_ID))
if hook_textbox.get_value() != elicitResponse['responsebot_hook']:
print(f'Value "{hook_textbox.get_value()}" does not match expected field value "{elicitResponse=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if 'response_sessionattr_name' in elicitResponse:
hook_textbox = Textbox(self.operator.select_id(RESPONSE_ATTRIBUTE_ID))
if hook_textbox.get_value() != elicitResponse['response_sessionattr_name']:
print(f'Value "{hook_textbox.get_value()}" does not match expected field value "{elicitResponse=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if kendraRedirectQueryText:
kendra_query_textbox = Textbox(self.operator.select_id(f'{type}-{KENDRA_REDIRECT_QUERY_ID}'))
if kendra_query_textbox.get_value() != kendraRedirectQueryText:
print(f'Value "{kendra_query_textbox.get_value()}" does not match expected field value "{kendraRedirectQueryText=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
kendra_confidence_textbox = Textbox(self.operator.select_id(f'{type}-{KENDRA_CONFIDENCE_ID}'))
if kendra_confidence_textbox.get_value() != kendraRedirectQueryConfidenceThreshold:
print(f'Value "{kendra_confidence_textbox.get_value()}" does not match expected field value "{kendraRedirectQueryConfidenceThreshold=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if conditionalChaining:
chaining_textbox = Textbox(self.operator.select_id(f'{type}-{CHAINING_ID}'))
if chaining_textbox.get_value() != conditionalChaining:
print(f'Value "{chaining_textbox.get_value()}" does not match expected field value "{conditionalChaining=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
for index, attribute in enumerate(sa):
sa_name_textbox = Textbox(self.operator.select_xpath(f'//div[@data-path="{type}.sa[{index}].text"]//input'))
if sa_name_textbox.get_value() != attribute['text']:
print(f'Value "{sa_name_textbox.get_value()}" does not match expected field value "{attribute=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
sa_value_textbox = Textbox(self.operator.select_xpath(f'//div[@data-path="{type}.sa[{index}].value"]//textarea'))
if sa_value_textbox.get_value() != attribute['value']:
print(f'Value "{sa_value_textbox.get_value()}" does not match expected field value "{attribute=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if botRouting:
bot_routing_textbox = Textbox(self.operator.select_id(BOT_ROUTING_ID))
if bot_routing_textbox.get_value() != botRouting['specialty_bot']:
print(f'Value "{bot_routing_textbox.get_value()}" does not match expected field value "{botRouting=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
bot_routing_textbox = Textbox(self.operator.select_id(BOT_ROUTING_NAME_ID))
if bot_routing_textbox.get_value() != botRouting['specialty_bot_name']:
print(f'Value "{bot_routing_textbox.get_value()}" does not match expected field value "{botRouting=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
bot_routing_textbox = Textbox(self.operator.select_id(BOT_ROUTING_ATTRIBUTE_ID))
if bot_routing_textbox.get_value() != botRouting['specialty_bot_session_attributes_to_merge']:
print(f'Value "{bot_routing_textbox.get_value()}" does not match expected field value "{botRouting=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if slots:
for index, slot in enumerate(slots):
name_textbox = Textbox(self.operator.select_xpath(f'//div[@data-path="qna.slots[{index}].slotName"]//input'))
if name_textbox.get_value() != slot['slotName']:
print(f'Value "{name_textbox.get_value()}" does not match expected field value "{slot=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
type_textbox = Textbox(self.operator.select_xpath(f'//div[@data-path="qna.slots[{index}].slotType"]//input'))
if type_textbox.get_value() != slot['slotType']:
print(f'Value "{type_textbox.get_value()}" does not match expected field value "{slot=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
prompt_textbox = Textbox(self.operator.select_xpath(f'//div[@data-path="qna.slots[{index}].slotPrompt"]//input'))
if prompt_textbox.get_value() != slot['slotPrompt']:
print(f'Value "{prompt_textbox.get_value()}" does not match expected field value "{slot=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if 'slotSampleUtterances' in slot:
utterances_textbox = Textbox(self.operator.select_xpath(f'//div[@data-path="qna.slots[{index}].slotSampleUtterances"]//input'))
if utterances_textbox.get_value() != slot['slotSampleUtterances']:
print(f'Value "{utterances_textbox.get_value()}" does not match expected field value "{slot=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if slotTypeValues:
for index, values in enumerate(slotTypeValues):
sample_value_textbox = Textbox(self.operator.select_xpath(f'//div[@data-path="slottype.slotTypeValues[{index}].samplevalue"]//input'))
if sample_value_textbox.get_value() != values['samplevalue']:
print(f'Value "{sample_value_textbox.get_value()}" does not match expected field value "{values=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
synonym_textbox = Textbox(self.operator.select_xpath(f'//div[@data-path="slottype.slotTypeValues[{index}].synonyms"]//input'))
if synonym_textbox.get_value() != values['synonyms']:
print(f'Value "{synonym_textbox.get_value()}" does not match expected field value "{values=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if passage:
passage_textbox = Textbox(self.operator.select_id(PASSAGE_ID))
if passage_textbox.get_value() != passage:
print(f'Value "{passage_textbox.get_value()}" does not match expected field value "{passage=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if clientFilterValues:
client_filter_textbox = Textbox(self.operator.select_id(f'{type}-{CLIENT_FILTER_ID}'))
if client_filter_textbox.get_value() != clientFilterValues:
print(f'Value "{client_filter_textbox.get_value()}" does not match expected field value "{clientFilterValues=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if refMarkdown:
ref_markdown_textbox = Textbox(self.operator.select_id(REF_MARKDOWN_ID))
if ref_markdown_textbox.get_value() != refMarkdown:
print(f'Value "{ref_markdown_textbox.get_value()}" does not match expected field value "{refMarkdown=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if tags:
tags_textbox = Textbox(self.operator.select_id(f'{type}-{TAGS_ID}'))
if tags_textbox.get_value() != tags:
print(f'Value "{tags_textbox.get_value()}" does not match expected field value "{tags=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if kendraRedirectQueryArgs:
for index, query_arg in enumerate(kendraRedirectQueryArgs):
query_arg_id = f'{type}-{KENDRA_REDIRECT_QUERY_ARGS_ID}-{index}'
query_arg_textbox = Textbox(self.operator.select_id(query_arg_id))
if query_arg_textbox.get_value() != query_arg:
print(f'Value "{query_arg_textbox.get_value()}" does not match expected field value "{query_arg=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if rp:
rp_textbox = Textbox(self.operator.select_id(f'{type}-{RP_ID}'))
if rp_textbox.get_value() != rp:
print(f'Value "{rp_textbox.get_value()}" does not match expected field value "{rp=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
if next:
next_textbox = Textbox(self.operator.select_id(f'{type}-{NEXT_ID}'))
if next_textbox.get_value() != next:
print(f'Value "{next_textbox.get_value()}" does not match expected field value "{next=}"')
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return False
self.operator.select_id(EDIT_QUESTION_CANCEL_ID, click=True)
return True
def delete_question_by_qid(self, qid: str):
"""
Deletes a question identified by its QID. Waits for confirmation of successful
deletion.
"""
self.operator.select_xpath(f'//span[@id="qa-{qid}-delete"]//descendant::button', wait=1, click=True)
self.operator.wait_for_element_by_xpath(CONFIRM_DELETE_XPATH)
self.operator.select_xpath(CONFIRM_DELETE_XPATH, click=True)
self.operator.wait_for_element_by_id(CONFIRM_DELETE_SUCCESS_ID, delay=20)
# Delete success modal sometimes does not appear - check to ensure it exists before interacting with button
if self.operator.element_exists_by_xpath(CONFIRM_DELETE_CLOSE_XPATH):
self.operator.select_xpath(CONFIRM_DELETE_CLOSE_XPATH, wait=1, click=True)
# After deleting multiple questions the XPATH points to the wrong QID in the table, so the table is refreshed
self.refresh_questions()
def select_question_by_qid(self, qid: str, column: int):
"""
Selects a question by its QID and column number. Returns the selected question.
"""
xpath = f'//*[@id="qa-{qid}"]/td[{column}]'
for i in range(5):
time.sleep(2 ** i)
if self.operator.element_exists_by_xpath(xpath):
break
print(f'Element {xpath} not ready. Waiting {2 ** (i + 1)}s.')
self.refresh_questions()
return self.operator.select_xpath(xpath)
def select_question_by_row_and_column(self, row: int, column: int):
"""
Selects a question by its row and column number. Returns the selected question.
"""
# Even rows are qa/answer content but are hidden, so we need to skip them
skip_row = row * 2 - 1
xpath = f'//table//tbody//tr[{skip_row}]/td[{column}]'
for i in range(5):
time.sleep(2 ** i)
if self.operator.element_exists_by_xpath(xpath):
break
print(f'Element {xpath} not ready. Waiting {2 ** (i + 1)}s.')
return self.operator.select_xpath(xpath)
def select_sub_menu(self) -> None:
"""
Selects the sub-menu on the current page.
"""
self.operator.select_id(SUB_MENU_ID, click=True)
def rebuild_lex(self) -> str:
"""
Rebuilds the bot and returns the status of the operation.
"""
self.select_sub_menu()
self.operator.select_id(REBUILD_LEX_ID, click=True)
success_status = self.operator.wait_for_element_by_id(REBUILD_LEX_SUCCESS_ID, delay=600).text
self.operator.select_id(REBUILD_LEX_CLOSE_ID, click=True)
time.sleep(1)
return success_status
def sync_kendra_faq(self):
"""
Synchronizes the Kendra FAQ and returns the status of the operation.
"""
self.select_sub_menu()
time.sleep(10)
self.operator.select_id(SYNC_KENDRA_FAQ_ID, click=True, wait=30)
success_status = self.operator.wait_for_element_by_id(SYNC_KENDRA_SUCCESS_ID, delay=180).text
self.operator.select_id(SYNC_KENDRA_CLOSE_ID, click=True)
return success_status
def select_test_tab(self):
"""
Selects the test tab on the edit page
"""
self.operator.select_xpath(TEST_TAB_XPATH, click=True)
self.operator.wait_for_element_by_id(TEST_TAB_QUERY_BUTTON_ID)
def select_test_all_tab(self):
"""
Selects the test all tab on the edit page
"""
self.operator.select_xpath(TEST_ALL_TAB_XPATH, click=True)
self.operator.wait_for_element_by_id(TEST_ALL_JOBS_ID)
def execute_test_query(self, query: str) -> None:
"""
Executes a test query on the test tab
"""
query_textbox = Textbox(self.operator.select_id(TEST_TAB_QUERY_ID))
query_textbox.set_value(query)
self.operator.select_id(TEST_TAB_QUERY_BUTTON_ID, click=True)
def generate_test_report(self) -> WebElement:
"""
Generates a test report and returns the text content of the job
"""
filename_textbox = Textbox(self.operator.select_id("filename"))
random_file_name = 'TestAll_' + ''.join(random.choices(string.ascii_letters + string.digits, k=4))
filename_textbox.set_value(random_file_name)
self.operator.select_id(TEST_ALL_BUTTON_ID, click=True)
self.operator.wait_for_element_by_xpath(f"//div[starts-with(@id, 'test-job-{random_file_name}')]")
last_test_execution_element = self.operator.select_xpath(f"//div[starts-with(@id, 'test-job-{random_file_name}')]")
self.operator.wait_for_element_by_id_text(last_test_execution_element.get_property("id"), 'Completed', delay=300)
return self.operator.select_id(last_test_execution_element.get_property("id"))
================================================
FILE: .nightswatch/functional/helpers/website_model/export_page.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
import time
from helpers.website_model.dom_operator import DomOperator
from helpers.utils.textbox import Textbox
FILENAME_ID = 'filename'
FILTER_ID = 'filter'
EXPORT_BUTTON_ID = 'export'
class ExportPage:
"""Class representing an ExportPage that allows the admin user to export questions.
This class provides methods to set filename, filter and generate export for the questions.
Attributes:
operator (DomOperator): An instance of DomOperator to manipulate and interact with the DOM.
"""
def __init__(self, operator: DomOperator) -> None:
"""
Initializes ExportPage with a DomOperator instance.
Args:
operator (DomOperator): An instance of DomOperator to manipulate and interact with the DOM.
"""
self.operator = operator
def __set_filename(self, filename: str):
"""
Private method to set the filename of the export file.
Args:
filename (str): The name of the export file.
"""
filename_textbox = Textbox(self.operator.select_id(FILENAME_ID, click=True))
filename_textbox.set_value(filename)
def __set_filter(self, filter: str):
"""
Private method to set the filter for the export operation.
Args:
filter (str): The filter for the export operation.
"""
filter_textbox = Textbox(self.operator.select_id(FILTER_ID, click=False))
filter_textbox.set_value(filter)
def generate_export(self, filename: str, filter: str):
"""
Generate an export file with the given filename and filter.
Args:
filename (str): The name of the export file.
filter (str): The filter for the export operation.
"""
self.__set_filename(filename)
self.__set_filter(filter)
self.operator.select_id(EXPORT_BUTTON_ID, click=True)
self.operator.wait_for_element_by_xpath(f'//div[@id="export-job-{filename}" and @data-status="Started"]//i[contains( text( ),"file_download")]//ancestor::button')
self.operator.wait_for_element_by_xpath(f'//div[@id="export-job-{filename}" and @data-status="Completed"]//i[contains( text( ),"file_download")]//ancestor::button')
self.operator.select_xpath(f'//div[@id="export-job-{filename}" and @data-status="Completed"]//i[contains( text( ),"file_download")]//ancestor::button', click=True)
================================================
FILE: .nightswatch/functional/helpers/website_model/import_page.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
from helpers.website_model.dom_operator import DomOperator
IMPORT_EXAMPLES_MENU_XPATH = '//button[@class="v-expansion-panel-title"]'
IMPORT_EXAMPLES_BLOG_EXAMPLE_ID = 'example-blog-samples-final'
IMPORT_LANGUAGE_ID = 'example-Language'
IMPORT_GREETING_HOOK_ID = 'example-GreetingHook'
EXPANSION_MENU_XPATH = '//button[@class="v-expansion-panel-title v-expansion-panel-title--active"]'
UPLOAD_FILE_ID = 'upload-file'
ERROR_MODAL_ID = 'error-modal'
class ImportPage:
"""Class representing an ImportPage that allows the admin user to import questions.
This class provides methods to expand examples, select examples, and import blog examples, language, and greeting hook.
Attributes:
operator (DomOperator): An instance of DomOperator to manipulate and interact with the DOM.
"""
def __init__(self, operator: DomOperator) -> None:
"""
Initializes ImportPage with a DomOperator instance.
Args:
operator (DomOperator): An instance of DomOperator to manipulate and interact with the DOM.
"""
self.operator = operator
self.__wait_to_load()
def __wait_to_load(self):
"""
A private method to wait for a page to load. Waits for a specific element
identified by its ID.
"""
self.operator.wait_for_element_by_id(UPLOAD_FILE_ID)
def __delete_existing_import_file_if_exists(self, file_name: str) -> None:
"""
A private method to delete the existing import file if it exists.
Args:
file_name (str): The name of the file to be deleted.
"""
file_element = f'//div[@id="import-job-{file_name}"]//button'
if self.operator.element_exists_by_xpath(file_element):
print(f'Deleting existing import file {file_name}')
self.operator.select_xpath(file_element, click=True)
def expand_examples(self) -> None:
"""
Expands the examples section on the import page.
"""
self.operator.select_xpath(IMPORT_EXAMPLES_MENU_XPATH, wait=10, click=True)
self.operator.wait_for_element_by_xpath(EXPANSION_MENU_XPATH)
def select_example(self, item: str) -> None:
"""
Selects an example from the examples section on the import page.
Args:
item (str): The CSS selector of the example to be selected.
"""
self.operator.select_css(item, wait=10, click=True)
def import_file(self, file: str) -> None:
"""
Imports a file on the import page.
:param file: The path to the file to be uploaded.
"""
file_name = file.split('/')[-1]
file_element = f'//div[@id="import-job-{file_name}" and @data-status="Complete"]'
self.__delete_existing_import_file_if_exists(file_name)
self.operator.wait_for_element_by_id(UPLOAD_FILE_ID)
self.operator.select_id(UPLOAD_FILE_ID).send_keys(file)
try:
self.operator.wait_for_element_by_xpath(file_element, delay=240)
except Exception as e:
print(f'Exception while waiting for import file element: {e}')
self.operator.driver.switch_to.alert.accept()
self.operator.wait_for_element_by_xpath(file_element, delay=240)
def get_import_file_error(self) -> None:
"""
Gets the error message from the error modal on the import page.
"""
self.operator.wait_for_element_by_xpath(f'//div[@id="{ERROR_MODAL_ID}"]//li')
return self.operator.select_id(ERROR_MODAL_ID).text
def import_blog_examples(self) -> None:
"""
Imports blog examples from the examples section on the import page.
"""
self.expand_examples()
self.operator.wait_for_element_by_id(IMPORT_EXAMPLES_BLOG_EXAMPLE_ID)
self.operator.click_element_by_id(IMPORT_EXAMPLES_BLOG_EXAMPLE_ID)
def import_language(self) -> None:
"""
Imports language examples from the examples section on the import page.
"""
self.expand_examples()
self.operator.wait_for_element_by_id(IMPORT_LANGUAGE_ID)
self.operator.click_element_by_id(IMPORT_LANGUAGE_ID)
def import_greeting_hook(self) -> None:
"""
Imports greeting hook examples from the examples section on the import page.
"""
self.expand_examples()
self.operator.wait_for_element_by_id(IMPORT_GREETING_HOOK_ID)
self.operator.click_element_by_id(IMPORT_GREETING_HOOK_ID)
================================================
FILE: .nightswatch/functional/helpers/website_model/kendra_page.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
import time
from helpers.website_model.dom_operator import DomOperator
KENDRA_INDEXING_BUTTON_XPATH = '//*[@id="btnKendraStartIndex"]'
KENDRA_INDEXING_BUTTON_ID = 'btnKendraStartIndex'
KENDRA_IMPORT_XPATH = '//div[@id="page-import"]//p'
SYNCING_TEXT = 'Current Status: SYNCING'
PAGE_READINESS_ELEMENT_XPATH = KENDRA_INDEXING_BUTTON_XPATH
class KendraPage:
"""Class representing a KendraPage that allows the admin user to trigger a re-index with Kendra.
This class provides a method to initiate the re-indexing process and return its status.
Attributes:
operator (DomOperator): An instance of DomOperator to manipulate and interact with the DOM.
"""
def __init__(self, operator: DomOperator) -> None:
"""
Initializes KendraPage with a DomOperator instance.
Args:
operator (DomOperator): An instance of DomOperator to manipulate and interact with the DOM.
"""
self.operator = operator
self.__wait_to_load()
def __wait_to_load(self):
"""
A private method to wait for a page to load. Waits for a specific element
identified by its ID.
"""
self.operator.wait_for_element_by_xpath(PAGE_READINESS_ELEMENT_XPATH)
def index(self) -> None:
"""
Triggers the re-indexing process with Kendra and returns the status of the operation.
Returns:
str: The status text of the re-indexing process.
"""
# self.operator.wait_for_element_by_xpath(KENDRA_INDEXING_BUTTON_XPATH)
time.sleep(2)
self.operator.click_element_by_id(KENDRA_INDEXING_BUTTON_ID)
self.operator.wait_for_element_by_xpath_text(KENDRA_IMPORT_XPATH, SYNCING_TEXT, delay=360)
status = self.operator.select_xpath(KENDRA_IMPORT_XPATH).text
return status
def get_crawling_status(self) -> None:
"""
Returns current Kendra crawling status
Returns:
str: Current Kendra crawling status
"""
# self.operator.wait_for_element_by_xpath(KENDRA_INDEXING_BUTTON_XPATH)
return self.operator.select_xpath(KENDRA_IMPORT_XPATH).text
================================================
FILE: .nightswatch/functional/helpers/website_model/login_page.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
import time
from helpers.website_model.dom_operator import DomOperator
from helpers.website_model.edit_page import EditPage
from helpers.website_model.chat_page import ChatPage
LOGOUT_ID = 'div-logout'
USERNAME_ID = 'signInFormUsername'
PASSWORD_ID = 'signInFormPassword'
SUBMIT_BUTTON_NAME = "signInSubmitButton"
class LoginPage:
"""Class representing a LoginPage that provides a way to log into the AWS cognito interface.
This class offers a method to log in to the AWS cognito interface using credentials.
It can handle login for two URLs - Question Designer and the Client Chat Bot.
Attributes:
operator (DomOperator): An instance of DomOperator to manipulate and interact with the DOM.
url (str): The URL of the destination page.
"""
def __init__(self, operator: DomOperator, url) -> None:
"""
Initializes LoginPage with a DomOperator instance and a URL.
Args:
operator (DomOperator): An instance of DomOperator to manipulate and interact with the DOM.
url (str): The URL of the destination page.
"""
self.operator = operator
self.url = url
def __is_client(self):
"""
Private method to determine if the current URL represents the client Chat Bot page.
Returns:
bool: True if the url is for the client, False otherwise.
"""
return 'client.html' in self.url
def login(self, username, password) -> str:
"""
Performs the login operation with the given credentials and returns the title of the loaded page.
Args:
username (str): The username to log in.
password (str): The password for the given username.
Returns:
str: The title of the page after successful login.
"""
self.operator.get_url(self.url)
self.operator.wait_for_element_by_id(USERNAME_ID, delay=5)
self.operator.set_window_size(800, 800)
designer_page = self.operator.select_xpath('/html/body')
if self.operator.get_title() == 'QnABot Client' or self.operator.get_title() == 'QnABot Designer':
return self.operator.get_title()
if 'Sign In as' in designer_page.text:
self.operator.select_id(LOGOUT_ID, click=True)
self.operator.select_id(USERNAME_ID).send_keys(username)
self.operator.select_id(PASSWORD_ID).send_keys(password)
self.operator.select_name(SUBMIT_BUTTON_NAME, click=True)
# Instantiating pages to wait for page readiness before exiting function
if self.__is_client():
ChatPage(self.operator)
else:
EditPage(self.operator)
output = self.operator.get_title()
if self.operator.element_exists_by_id('loginErrorMessage'):
if password == 'invalidPassword':
output = (output, self.operator.select_id('loginErrorMessage').text)
else:
raise RuntimeError(self.operator.select_id('loginErrorMessage').text)
return output
================================================
FILE: .nightswatch/functional/helpers/website_model/menu_nav.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
import time
from helpers.website_model.edit_page import EditPage
from helpers.website_model.import_page import ImportPage
from helpers.website_model.export_page import ExportPage
from helpers.website_model.settings_page import SettingsPage
from helpers.website_model.kendra_page import KendraPage
from helpers.website_model.custom_terminology_page import CustomTerminologyPage
from helpers.website_model.dom_operator import DomOperator
from helpers.website_model.login_page import LoginPage
from helpers.website_model.chat_page import ChatPage
MENU_ID = 'nav-open'
LOGOUT_ID = 'logout-button'
EDIT_PAGE_ID = 'page-link-edit'
EDIT_ID = 'page-link-edit'
EXPORT_PAGE_ID = 'page-link-export'
IMPORT_PAGE_ID = 'page-link-import'
SETTINGS_ID = 'page-link-settings'
KENDRA_ID = 'page-link-kendraIndexing'
CUSTOM_TERM_ID = 'page-link-customTranslate'
CHAT_ID = 'page-link-client'
TEST_ALL_ID = 'testAll-tab'
class MenuNav:
"""Class representing a Menu Navigation Bar.
This class provides a way to navigate through different pages in the application by selecting menu options.
It is used across all administrative pages.
Attributes:
operator (DomOperator): An instance of DomOperator to manipulate and interact with the DOM.
"""
def __init__(self, operator: DomOperator) -> None:
"""
Initializes the MenuNav with a DomOperator instance.
Args:
operator (DomOperator): An instance of DomOperator to manipulate and interact with the DOM.
"""
self.operator = operator
def select_menu(self) -> None:
"""Selects the menu in the navigation bar."""
self.operator.click_element_by_id(MENU_ID, wait=10)
def __from_menu_select_item(self, item: str) -> None:
"""
Private method to select an item from the menu.
Args:
item (str): The CSS selector of the menu item to be selected.
"""
self.operator.select_css(item, wait=10, click=True)
def logout(self) -> LoginPage:
"""Logs out the current user and returns the LoginPage instance."""
self.operator.select_id(LOGOUT_ID, wait=10, click=True)
return LoginPage(self.operator, self.operator.get_current_url())
def open_import_page(self) -> ImportPage:
"""Opens the ImportPage through the menu and returns its instance."""
self.select_menu()
self.operator.select_id(IMPORT_PAGE_ID, wait=10, click=True)
return ImportPage(self.operator)
def open_export_page(self) -> ExportPage:
"""Opens the ExportPage through the menu and returns its instance."""
self.select_menu()
self.operator.select_id(EXPORT_PAGE_ID, wait=10, click=True)
return ExportPage(self.operator)
def open_edit_page(self) -> EditPage:
"""Opens the EditPage through the menu and returns its instance."""
self.select_menu()
self.operator.wait_for_element_by_id(EDIT_ID)
self.operator.click_element_by_id(EDIT_PAGE_ID, wait=10)
return EditPage(self.operator)
def open_settings_page(self) -> SettingsPage:
"""Opens the SettingsPage through the menu and returns its instance."""
self.select_menu()
self.operator.select_id(SETTINGS_ID, wait=10, click=True)
return SettingsPage(self.operator)
def open_kendra_page(self) -> KendraPage:
"""Opens the KendraPage through the menu and returns its instance."""
self.select_menu()
self.operator.select_id(KENDRA_ID, wait=10, click=True)
return KendraPage(self.operator)
def open_custom_terminology(self) -> CustomTerminologyPage:
"""Opens the CustomTerminologyPage through the menu and returns its instance."""
self.select_menu()
self.operator.select_id(CUSTOM_TERM_ID, wait=10, click=True)
return CustomTerminologyPage(self.operator)
def open_chat_page(self) -> ChatPage:
"""Opens the ChatPage through the menu, switches to its window and returns its instance."""
self.select_menu()
self.operator.click_element_by_id(CHAT_ID, wait=10)
time.sleep(5)
self.operator.switch_windows()
return ChatPage(self.operator)
def open_testall_page(self) -> None:
"""Opens the TestAllPage through navigation bar."""
self.operator.click_element_by_id(TEST_ALL_ID, wait=10)
time.sleep(5)
================================================
FILE: .nightswatch/functional/helpers/website_model/settings_page.py
================================================
######################################################################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. #
# SPDX-License-Identifier: Apache-2.0 #
######################################################################################################################
import time
import os
import selenium
from helpers.utils.textbox import Textbox
from helpers.website_model.dom_operator import DomOperator
EMPTY_MESSAGE_ID = 'EMPTYMESSAGE'
MULTI_LANGUAGE_SUPPORT_ID = 'ENABLE_MULTI_LANGUAGE_SUPPORT'
ENABLE_KENDRA_ID = 'ENABLE_KENDRA_WEB_INDEXER'
ENABLE_KENDRA_FALLBACK_ID = 'KENDRA_FAQ_ES_FALLBACK'
KENDRA_INDEX_ID = 'KENDRA_INDEXER_URLS'
ENABLE_EMBEDDINGS_ID = 'EMBEDDINGS_ENABLE'
EMBEDDINGS_SCORE_THRESHOLD_ID = 'EMBEDDINGS_SCORE_THRESHOLD'
EMBEDDINGS_SCORE_ANSWER_THRESHOLD_ID = 'EMBEDDINGS_SCORE_ANSWER_THRESHOLD'
EMBEDDINGS_TEXT_PASSAGE_SCORE_THRESHOLD_ID = 'EMBEDDINGS_TEXT_PASSAGE_SCORE_THRESHOLD'
ENABLE_CUSTOM_TERMINOLOGY_ID = 'ENABLE_CUSTOM_TERMINOLOGY'
ENABLE_FILTER_ID = 'ES_USE_KEYWORD_FILTERS'
FILTER_CRITERIA_ID = 'ES_MINIMUM_SHOULD_MATCH'
KENDRA_INDEXER_CRAWL_DEPTH_ID = 'KENDRA_INDEXER_CRAWL_DEPTH'
KENDRA_INDEXER_MODE_ID = 'KENDRA_INDEXER_CRAWL_MODE'
KENDRA_INDEXER_SCHEDULE_ID = 'KENDRA_INDEXER_SCHEDULE'
KENDRA_MAX_DOCUMENT_COUNT = 'ALT_SEARCH_KENDRA_MAX_DOCUMENT_COUNT'
ENABLE_DEBUG_RESPONSES_ID = 'ENABLE_DEBUG_RESPONSES'
ES_SCORE_TEXT_ITEM_PASSAGES_ID = 'ES_SCORE_TEXT_ITEM_PASSAGES'
LLM_GENERATE_QUERY_ENABLE_ID = 'LLM_GENERATE_QUERY_ENABLE'
LLM_QA_ENABLE_ID = 'LLM_QA_ENABLE'
LLM_QA_USE_KENDRA_RETRIEVAL_API_ID = 'LLM_QA_USE_KENDRA_RETRIEVAL_API'
LLM_QA_SHOW_CONTEXT_TEXT_ID = 'LLM_QA_SHOW_CONTEXT_TEXT'
LLM_QA_SHOW_SOURCE_LINKS_ID = 'LLM_QA_SHOW_SOURCE_LINKS'
PRE_PROCESSING_LAMBDA_ID = 'LAMBDA_PREPROCESS_HOOK'
POST_PROCESSING_LAMBDA_ID = 'LAMBDA_POSTPROCESS_HOOK'
SAVE_XPATH = "//button[span='Save']"
RESET_XPATH = "//button[span='Reset to defaults']"
SAVE_STATUS_CSS = '#error-modal'
SAVE_MODAL_CLOSE_XPATH = "//button[span='close']"
CHATBOT_TESTING_SUBGROUP_ID = 'chatbot_testing_subgroup'
LANGUAGE_IDENTIFICATION_SUBGROUP_ID = 'language_identification_subgroup'
OPEN_SEARCH_SUBGROUP_ID = 'opensearch_subgroup'
SECURITY_AND_PRIVACY_SUBGROUP_ID = 'security_and_privacy_subgroup'
QUERY_MATCHING_SUBGROUP_ID = 'query_matching_subgroup'
AMAZON_LEX_SUBGROUP_ID = 'amazon_lex_subgroup'
ADVANCED_SUBGROUP_ID = 'advanced_subgroup'
AMAZON_CONNECT_SUBGROUP_ID = 'amazon_connect_subgroup'
AMAZON_ALEXA_SUBGROUP_ID = 'amazon_alexa_subgroup'
AMAZON_KENDRA_SUBGROUP_ID = 'amazon_kendra_subgroup'
TEXT_GENERATION_GENERAL_SUBGROUP_ID = 'text_generation_general_subgroup'
AMAZON_BEDROCK_KNOWLEDGE_BASES_SUBGROUP_ID = 'amazon_bedrock_knowledge_bases_subgroup'
KNOWLEDGE_BASE_SEARCH_TYPE_ID = 'KNOWLEDGE_BASE_SEARCH_TYPE'
KNOWLEDGE_BASE_MAX_NUMBER_OF_RETRIEVED_RESULTS_ID = 'KNOWLEDGE_BASE_MAX_NUMBER_OF_RETRIEVED_RESULTS'
KNOWLEDGE_BASE_MODEL_PARAMS_ID = 'KNOWLEDGE_BASE_MODEL_PARAMS'
KNOWLEDGE_BASE_PROMPT_TEMPLATE_ID = 'KNOWLEDGE_BASE_PROMPT_TEMPLATE'
BEDROCK_GUARDRAIL_IDENTIFIER_ID = 'BEDROCK_GUARDRAIL_IDENTIFIER'
BEDROCK_GUARDRAIL_VERSION_ID = 'BEDROCK_GUARDRAIL_VERSION'
BEDROCK_GUARDRAIL_SUBGROUP_ID = 'text_generation_guardrail_subgroup'
PREPROCESS_GUARDRAIL_IDENTIFIER_ID = 'PREPROCESS_GUARDRAIL_IDENTIFIER'
PREPROCESS_GUARDRAIL_VERSION_ID = 'PREPROCESS_GUARDRAIL_VERSION'
POSTPROCESS_GUARDRAIL_IDENTIFIER_ID = 'POSTPROCESS_GUARDRAIL_IDENTIFIER'
POSTPROCESS_GUARDRAIL_VERSION_ID = 'POSTPROCESS_GUARDRAIL_VERSION'
class SettingsPage:
"""
Class representing a Settings Page.
This class provides methods to interact with and manipulate the settings of Q&A bot.
Attributes:
operator (DomOperator): An instance of DomOperator to manipulate and interact with the DOM.
"""
def __init__(self, operator: DomOperator) -> None:
"""
Initializes the SettingsPage with a DomOperator instance.
Args:
operator (DomOperator): An instance of DomOperator to manipulate and interact with the DOM.
"""
self.operator = operator
def save_settings(self) -> str:
"""Saves the current settings and returns the status of the operation."""
self.operator.select_xpath(SAVE_XPATH, click=True)
self.operator.wait_for_element_by_xpath(SAVE_MODAL_CLOSE_XPATH)
time.sleep(2)
status = self.operator.select_css(SAVE_STATUS_CSS).text
self.operator.select_xpath(SAVE_MODAL_CLOSE_XPATH, click=True)
return status
def reset_settings(self) -> str:
"""Resets the current settings."""
self.operator.select_xpath(RESET_XPATH, click=True)
time.sleep(1)
def select_setting_by_label(self, label: str):
"""
Selects a setting by its label.
Args:
label (str): The label of the setting to select.
Returns:
The selected WebElement.
"""
return self.operator.select_id(label, click=False)
def __set_element_value(self, element, value):
"""
Private method to set the value of a WebElement.
Args:
element: The WebElement to update.
value: The value to set in the WebElement.
"""
textbox = Textbox(element)
textbox.set_value(value)
def __get_element_value(self, element) -> str:
"""
Private method to get the value of a WebElement.
Args:
element: The WebElement to update.
Returns:
The value of the WebElement.
"""
textbox = Textbox(element)
return textbox.get_value()
def customize_empty_message(self, message) -> str:
"""
Customizes the empty message setting and saves the changes.
Args:
message (str): The new empty message.
Returns:
The status of the save operation.
"""
customize_empty_message = self.operator.select_id(EMPTY_MESSAGE_ID)
self.__set_element_value(customize_empty_message, message)
return self.save_settings()
def enable_debug_response(self) -> str:
"""
Enables debug responses during the chat conversation and saves the changes.
Returns:
The status of the save operation.
"""
enable_debug = self.operator.select_id(ENABLE_DEBUG_RESPONSES_ID)
self.__set_element_value(enable_debug, 'true')
return self.save_settings()
def enable_multi_language_support(self) -> str:
"""
Enables the multi-language support setting and saves the changes.
Returns:
The status of the save operation.
"""
enable_multi_language_support = self.operator.select_id(MULTI_LANGUAGE_SUPPORT_ID)
self.__set_element_value(enable_multi_language_support, 'true')
return self.save_settings()
def enable_kendra(self, indexer_url: str, depth: int=2, mode: str='subdomains', schedule: str='rate(1 day)', doc_count: str='10') -> str:
"""
Enables the Kendra setting and configures Kendra parameters.
Args:
indexer_url (str): The URL of the indexer.
depth (int, optional): The crawl depth. Defaults to 3.
mode (str, optional): The indexing mode. Defaults to 'subdomains'.
schedule (str, optional): The indexing schedule. Defaults to 'rate(1 day)'.
doc_count (str, optional): The number of docs returned by Kendra. Defaults to '10'.
Returns:
The status of the save operation.
"""
enable_kendra_web_indexer = self.operator.select_id(ENABLE_KENDRA_ID)
self.__set_element_value(enable_kendra_web_indexer, 'true')
update_kendra_indexer_urls = self.operator.select_id(KENDRA_INDEX_ID)
self.__set_element_value(update_kendra_indexer_urls, indexer_url)
update_kendra_indexer_crawl_depth = self.operator.select_id(KENDRA_INDEXER_CRAWL_DEPTH_ID)
self.__set_element_value(update_kendra_indexer_crawl_depth, depth)
update_kendra_indexer_mode = self.operator.select_id(KENDRA_INDEXER_MODE_ID)
self.__set_element_value(update_kendra_indexer_mode, mode)
update_kendra_indexer_schedule = self.operator.select_id(KENDRA_INDEXER_SCHEDULE_ID)
self.__set_element_value(update_kendra_indexer_schedule, schedule)
update_kendra_doc_count = self.operator.select_id(KENDRA_MAX_DOCUMENT_COUNT)
self.__set_element_value(update_kendra_doc_count, doc_count)
return self.save_settings()
def enable_kendra_fallback(self) -> str:
"""
Enables the Kendra fallback setting.
Returns:
The status of the save operation.
"""
enable_kendra_web_indexer = self.operator.select_id(ENABLE_KENDRA_FALLBACK_ID)
self.__set_element_value(enable_kendra_web_indexer, 'true')
return self.save_settings()
def disable_kendra_fallback(self) -> str:
"""
Disables the Kendra fallback setting.
Returns:
The status of the save operation.
"""
enable_kendra_web_indexer = self.operator.select_id(ENABLE_KENDRA_FALLBACK_ID)
self.__set_element_value(enable_kendra_web_indexer, 'false')
return self.save_settings()
def enable_embeddings(self) -> str:
"""
Enables the embeddings setting and saves the changes.
Returns:
The status of the save operation.
"""
enable_embeddings = self.operator.select_id(ENABLE_EMBEDDINGS_ID)
self.__set_element_value(enable_embeddings, 'true')
return self.save_settings()
def disable_embeddings(self) -> str:
"""
Disables the embeddings setting and saves the changes.
Returns:
The status of the save operation.
"""
disable_embeddings = self.operator.select_id(ENABLE_EMBEDDINGS_ID)
self.__set_element_value(disable_embeddings, 'false')
return self.save_settings()
def enable_llm(self) -> str:
"""
Enables LLM setting and saves the changes.
Returns:
The status of the save operation.
"""
enable_debug = self.operator.select_id(ENABLE_DEBUG_RESPONSES_ID)
self.__set_element_value(enable_debug, 'true')
enable_item_passages = self.operator.select_id(ES_SCORE_TEXT_ITEM_PASSAGES_ID)
self.__set_element_value(enable_item_passages, 'true')
enable_generative_query = self.operator.select_id(LLM_GENERATE_QUERY_ENABLE_ID)
self.__set_element_value(enable_generative_query, 'true')
enable_llm_qa = self.operator.select_id(LLM_QA_ENABLE_ID)
self.__set_element_value(enable_llm_qa, 'true')
enable_llm_kendra = self.operator.select_id(LLM_QA_USE_KENDRA_RETRIEVAL_API_ID)
self.__set_element_value(enable_llm_kendra, 'true')
enable_show_context_text = self.operator.select_id(LLM_QA_SHOW_CONTEXT_TEXT_ID)
self.__set_element_value(enable_show_context_text, 'true')
enable_source_links = self.operator.select_id(LLM_QA_SHOW_SOURCE_LINKS_ID)
self.__set_element_value(enable_source_links, 'true')
return self.save_settings()
def disable_llm(self) -> str:
"""
Disables LLM setting and saves the changes.
Returns:
The status of the save operation.
"""
enable_item_passages = self.operator.select_id(ES_SCORE_TEXT_ITEM_PASSAGES_ID)
self.__set_element_value(enable_item_passages, 'false')
enable_generative_query = self.operator.select_id(LLM_GENERATE_QUERY_ENABLE_ID)
self.__set_element_value(enable_generative_query, 'false')
enable_llm_qa = self.operator.select_id(LLM_QA_ENABLE_ID)
self.__set_element_value(enable_llm_qa, 'false')
enable_llm_kendra = self.operator.select_id(LLM_QA_USE_KENDRA_RETRIEVAL_API_ID)
self.__set_element_value(enable_llm_kendra, 'false')
enable_show_context_text = self.operator.select_id(LLM_QA_SHOW_CONTEXT_TEXT_ID)
self.__set_element_value(enable_show_context_text, 'false')
enable_source_links = self.operator.select_id(LLM_QA_SHOW_SOURCE_LINKS_ID)
self.__set_element_value(enable_source_links, 'false')
return self.save_settings()
def disable_llm_disambiguation(self):
enable_generative_query = self.operator.select_id(LLM_GENERATE_QUERY_ENABLE_ID)
self.__set_element_value(enable_generative_query, 'false')
return self.save_settings()
def enable_bedrock_guardrail(self, region, guardrail_identifier, guardrail_version, selector='bedrock'):
"""
Enables the Bedrock guardrail for functional tests based on the nightswatch or local environment.
Args:
region (str): The region for the guardrail.
Returns:
The status of the save operation.
"""
mappings = {
'us-east-1': ('6wptcgn6mi7x', 2),
'us-west-2': ('nnbn5202wy5g', 2),
'eu-west-2': ('jsj81qgv3ky5', 2),
'ap-northeast-1': ('672yn8u1u3v5', 1),
'ap-southeast-1': ('9svj21mhvizz', 1),
'ap-southeast-2': ('8t3dz616x886', 1),
'ca-central-1': ('vci2abppnly8', 1),
'eu-central-1': ('kxzczv00h33w', 1),
}
if os.getenv('NIGHTSWATCH_TEST_DIR'):
guardrail_identifier = mappings[region][0]
guardrail_version = mappings[region][1]
if not guardrail_identifier or not guardrail_version:
return self.save_settings()
valid_selectors = ['bedrock', 'preprocess', 'postprocess']
if selector not in valid_selectors:
raise ValueError(f"Invalid selector. Must be one of {valid_selectors}")
selector_id = BEDROCK_GUARDRAIL_IDENTIFIER_ID
selector_version_id = BEDROCK_GUARDRAIL_VERSION_ID
if selector == 'preprocess':
selector_id = PREPROCESS_GUARDRAIL_IDENTIFIER_ID
selector_version_id = PREPROCESS_GUARDRAIL_VERSION_ID
if selector == 'postprocess':
selector_id = POSTPROCESS_GUARDRAIL_IDENTIFIER_ID
selector_version_id = POSTPROCESS_GUARDRAIL_VERSION_ID
get_guardrail_identifier = self.operator.select_id(selector_id)
self.__set_element_value(get_guardrail_identifier, guardrail_identifier)
get_guardrail_version = self.operator.select_id(selector_version_id)
self.__set_element_value(get_guardrail_version, guardrail_version)
return self.save_settings()
def enable_custom_terminology(self) -> str:
"""
Enables the custom terminology setting and saves the changes.
Returns:
The status of the save operation.
"""
enable_custom_terminology = self.operator.select_id(ENABLE_CUSTOM_TERMINOLOGY_ID)
self.__set_element_value(enable_custom_terminology, 'true')
return self.save_settings()
def enable_filter(self) -> str:
"""
Enables the filter setting and saves the changes.
Returns:
The status of the save operation.
"""
enable_filter = self.operator.select_id(ENABLE_FILTER_ID)
self.__set_element_value(enable_filter, 'true')
return self.save_settings()
def disable_filter(self) -> str:
"""
Disables the filter setting and saves the changes.
Returns:
The status of the save operation.
"""
disable_filter = self.operator.select_id(ENABLE_FILTER_ID)
self.__set_element_value(disable_filter, 'false')
return self.save_settings()
def set_match_criteria(self, criteria: str) -> str:
"""
Sets the match criteria setting and saves the changes.
Args:
criteria (str): The match criteria to set.
Returns:
The status of the save operation.
"""
match_criteria = self.operator.select_id(FILTER_CRITERIA_ID)
self.__set_element_value(match_criteria, criteria)
return self.save_settings()
def get_no_hits_response(self) -> str:
"""
Returns the no hits response from the settings page.
Returns:
The no hits response from the settings page.
"""
ho_hits = self.operator.select_id(EMPTY_MESSAGE_ID)
return self.__get_element_value(ho_hits)
def set_pre_processing_lambda(self, l: str) -> str:
"""
Sets the pre-processing lambda setting and saves the changes.
Args:
l (str): The lambda function to set.
Returns:
The status of the save operation.
"""
pre_processing_lambda = self.operator.select_id(PRE_PROCESSING_LAMBDA_ID)
self.__set_element_value(pre_processing_lambda, l)
return self.save_settings()
def set_post_processing_lambda(self, l: str) -> str:
"""
Sets the post-processing lambda setting and saves the changes.
Args:
l (str): The lambda function to set.
Returns:
The status of the save operation.
"""
post_processing_lambda = self.operator.select_id(POST_PROCESSING_LAMBDA_ID)
self.__set_element_value(post_processing_lambda, l)
return self.save_settings()
def disable_kb_prompt(self) -> str:
"""
Disables prompt for knowledge base which is enabled by default
Returns:
The status of the save operation.
"""
kb_prompt = self.operator.select_id(KNOWLEDGE_BASE_PROMPT_TEMPLATE_ID)
self.__set_element_value(kb_prompt, '')
return self.save_settings()
def enable_kb_advanced(self, knowledge_base_model) -> str:
"""
Enables advanced settings for the knowledge base
Returns:
The status of the save operation.
"""
kb_search_type = self.operator.select_id(KNOWLEDGE_BASE_SEARCH_TYPE_ID)
kb_max_results = self.operator.select_id(KNOWLEDGE_BASE_MAX_NUMBER_OF_RETRIEVED_RESULTS_ID)
kb_model_params = self.operator.select_id(KNOWLEDGE_BASE_MODEL_PARAMS_ID)
if knowledge_base_model.startswith('anthropic'):
self.__set_element_value(kb_search_type, 'HYBRID')
self.__set_element_value(kb_max_results, 4)
self.__set_element_value(kb_model_params, '{"temperature": 0.1, "maxTokens": 300, "topP": 0.9, "top_k": 240 }')
else:
self.__set_element_value(kb_search_type, 'HYBRID')
self.__set_element_value(kb_max_results, 5)
self.__set_element_value(kb_model_params, '{"temperature": 0.1, "maxTokens": 300, "topP": 0.9 }')
return self.save_settings()
def expand_all_subgroups(self) -> None:
"""
Expands all subgroups in the settings page.
"""
try:
chatbot_testing_subgroup = self.operator.select_id(CHATBOT_TESTING_SUBGROUP_ID)
if chatbot_testing_subgroup.get_attribute('aria-expanded') == 'false':
chatbot_testing_subgroup.click()
self.operator.wait_for_element_attribute(CHATBOT_TESTING_SUBGROUP_ID, 'aria-expanded', 'true')
language_identification_subgroup = self.operator.select_id(LANGUAGE_IDENTIFICATION_SUBGROUP_ID)
if language_identification_subgroup.get_attribute('aria-expanded') == 'false':
language_identification_subgroup.click()
self.operator.wait_for_element_attribute(LANGUAGE_IDENTIFICATION_SUBGROUP_ID, 'aria-expanded', 'true')
opensearch_subgroup = self.operator.select_id(OPEN_SEARCH_SUBGROUP_ID)
if opensearch_subgroup.get_attribute('aria-expanded') == 'false':
opensearch_subgroup.click()
self.operator.wait_for_element_attribute(OPEN_SEARCH_SUBGROUP_ID, 'aria-expanded', 'true')
security_and_privacy_subgroup = self.operator.select_id(SECURITY_AND_PRIVACY_SUBGROUP_ID)
if security_and_privacy_subgroup.get_attribute('aria-expanded') == 'false':
security_and_privacy_subgroup.click()
self.operator.wait_for_element_attribute(SECURITY_AND_PRIVACY_SUBGROUP_ID, 'aria-expanded', 'true')
query_matching_subgroup = self.operator.select_id(QUERY_MATCHING_SUBGROUP_ID)
if query_matching_subgroup.get_attribute('aria-expanded') == 'false':
query_matching_subgroup.click()
self.operator.wait_for_element_attribute(QUERY_MATCHING_SUBGROUP_ID, 'aria-expanded', 'true')
advanced_subgroup = self.operator.select_id(ADVANCED_SUBGROUP_ID)
if advanced_subgroup.get_attribute('aria-expanded') == 'false':
advanced_subgroup.click()
self.operator.wait_for_element_attribute(ADVANCED_SUBGROUP_ID, 'aria-expanded', 'true')
amazon_lex_subgroup = self.operator.select_id(AMAZON_LEX_SUBGROUP_ID)
if amazon_lex_subgroup.get_attribute('aria-expanded') == 'false':
amazon_lex_subgroup.click()
self.operator.wait_for_element_attribute(AMAZON_LEX_SUBGROUP_ID, 'aria-expanded', 'true')
amazon_connect_subgroup = self.operator.select_id(AMAZON_CONNECT_SUBGROUP_ID)
if amazon_connect_subgroup.get_attribute('aria-expanded') == 'false':
amazon_connect_subgroup.click()
self.operator.wait_for_element_attribute(AMAZON_CONNECT_SUBGROUP_ID, 'aria-expanded', 'true')
amazon_alexa_subgroup = self.operator.select_id(AMAZON_ALEXA_SUBGROUP_ID)
if amazon_alexa_subgroup.get_attribute('aria-expanded') == 'false':
amazon_alexa_subgroup.click()
self.operator.wait_for_element_attribute(AMAZON_ALEXA_SUBGROUP_ID, 'aria-expanded', 'true')
amazon_kendra_subgroup = self.operator.select_id(AMAZON_KENDRA_SUBGROUP_ID)
if amazon_kendra_subgroup.get_attribute('aria-expanded') == 'false':
amazon_kendra_subgroup.click()
self.operator.wait_for_element_attribute(AMAZON_KENDRA_SUBGROUP_ID, 'aria-expanded', 'true')
text_generation_general_subgroup = self.operator.select_id(TEXT_GENERATION_GENERAL_SUBGROUP_ID)
if text_generation_general_subgroup.get_attribute('aria-expanded') == 'false':
text_generation_general_subgroup.click()
self.operator.wait_for_element_attribute(TEXT_GENERATION_GENERAL_SUBGROUP_ID, 'aria-expanded', 'true')
amazon_bedrock_knowledge_bases_subgroup = self.operator.select_id(AMAZON_BEDROCK_KNOWLEDGE_BASES_SUBGROUP_ID)
if amazon_bedrock_knowledge_bases_subgroup.get_attribute('aria-expanded') == 'false':
amazon_bedrock_knowledge_bases_subgroup.click()
self.operator.wait_for_element_attribute(AMAZON_BEDROCK_KNOWLEDGE_BASES_SUBGROUP_ID, 'aria-expanded', 'true')
bedrock_guardrail_general_subgroup = self.operator.select_id(BEDROCK_GUARDRAIL_SUBGROUP_ID)
if bedrock_guardrail_general_subgroup.get_attribute('aria-expanded') == 'false':
bedrock_guardrail_general_subgroup.click()
self.operator.wait_for_element_attribute(BEDROCK_GUARDRAIL_SUBGROUP_ID, 'aria-expanded', 'true')
except selenium.common.exceptions.ElementClickInterceptedException:
# The exception above happens when a window obscures the settings page,
# In this case it is safe to ignore that error and continue on with the test.
pass
================================================
FILE: .nightswatch/functional/pytest.ini
================================================
[pytest]
log_cli = true
log_cli_date_format = %Y-%m-%d %H:%M:%S
log_cli_format = %(asctime)s %(levelname)s %(message)s
log_cli_level = INFO
log_file = regression_tests_run.log
log_file_date_format = %Y-%m-%d %H:%M:%S
log_file_format = %(asctime)s %(levelname)s %(message)s
markers =
skipif_kendra_not_enabled
skipif_llm_not_enabled
skipif_embeddings_not_enabled
skipif_knowledge_base_not_enabled
skipif_version_less_than
================================================
FILE: .nightswatch/functional/question_bank/embeddings_questions.json
================================================
{
"qna": [
{
"a": "1600 Pennsylvania Ave., NW, Washington, DC 20500",
"type": "qna",
"qid": "Embed.001",
"q": [
"What is the address of the White House?"
]
}
]
}
================================================
FILE: .nightswatch/functional/question_bank/guardrail_question.json
================================================
{
"qna": [
{
"a": "The credit card is 1111-1111-1111-1111",
"type": "qna",
"qid": "Guardrail.001",
"q": [
"Is their a credit card number stored in your database?"
]
}
]
}
================================================
FILE: .nightswatch/functional/question_bank/import_questions.json
================================================
{
"qna": [
{
"q": [
"Which file formats are supported by the QnA Bot question designer import?"
],
"a": "JSON and xlsx.",
"qid": "Import.001"
}
]
}
================================================
FILE: .nightswatch/functional/question_bank/import_questions_qna.json
================================================
{
"qna": [
{
"next": "NextQid",
"a": "Answer",
"enableQidIntent": true,
"kendraRedirectQueryText": "KendraRedirect",
"elicitResponse": {
"response_sessionattr_namespace": "Namespace",
"responsebot_hook": "QNAYesNo"
},
"alt": {
"markdown": "markdown",
"ssml": "SSML"
},
"conditionalChaining": "DocumentChaining",
"l": "LambdaHook",
"type": "qna",
"qid": "Import.004",
"sa": [
{
"enableTranslate": true,
"text": "AttributeName1",
"value": "AttributeValue1"
},
{
"text": "AttributeName2",
"value": "AttributeValue2"
}
],
"kendraRedirectQueryConfidenceThreshold": "LOW",
"clientFilterValues": "ClientFilter",
"tags": "Tags",
"args": [
"HookArg1",
"HookArg2"
],
"slots": [
{
"slotName": "SlotName1",
"slotPrompt": "SlotPrompt1",
"slotRequired": true,
"slotType": "SlotType1",
"slotValueCached": true,
"slotSampleUtterances": "SlotUtterances1"
},
{
"slotName": "SlotName2",
"slotPrompt": "SlotPrompt2",
"slotType": "SlotType2",
"slotSampleUtterances": "SlotUtterances2"
}
],
"r": {
"buttons": [
{
"text": "ButtonText1",
"value": "ButtonValue1"
},
{
"text": "ButtonText2",
"value": "ButtonValue2"
}
],
"subTitle": "CardSubtitle",
"imageUrl": "CardUrl",
"title": "CardTitle"
},
"t": "Topic",
"kendraRedirectQueryArgs": [
"KendraArg1",
"KendraArg2"
],
"botRouting": {
"specialty_bot": "lexv2::7T1CYCPYVK",
"specialty_bot_name": "Testbot",
"specialty_bot_session_attributes_to_merge": "1,2,3"
},
"rp": "AlexaReprompt",
"q": [
"Question1",
"Question2"
]
}
]
}
================================================
FILE: .nightswatch/functional/question_bank/import_questions_slot.json
================================================
{
"qna": [
{
"descr": "Description",
"resolutionStrategyRestrict": true,
"type": "slottype",
"qid": "Import.006",
"slotTypeValues": [
{
"synonyms": "Synonyms",
"samplevalue": "Value1"
},
{
"synonyms": "Synonyms2",
"samplevalue": "Value2"
}
]
}
]
}
================================================
FILE: .nightswatch/functional/question_bank/import_questions_text.json
================================================
{
"qna": [
{
"passage": "Passage",
"kendraRedirectQueryText": "KendraRedirect",
"refMarkdown": "ReferenceLinks",
"conditionalChaining": "ChainingRule",
"l": "LambdaHook",
"type": "text",
"qid": "Import.007",
"sa": [
{
"enableTranslate": true,
"text": "SessionAttributeName1",
"value": "SessionAttributeValue1"
},
{
"text": "SessionAttributeName2",
"value": "SessionAttributeValue2"
}
],
"kendraRedirectQueryConfidenceThreshold": "LOW",
"clientFilterValues": "ClientFilter",
"tags": "Tags",
"args": [
"Arg1",
"Arg2"
],
"r": {
"buttons": [
{
"text": "ButtonText1",
"value": "ButtonValue1"
},
{
"text": "ButtonText2",
"value": "ButtonValue2"
}
],
"subTitle": "CardSubtitle",
"imageUrl": "CardUrl",
"title": "CardTitle"
},
"t": "Topic",
"kendraRedirectQueryArgs": [
"KendraQuery1",
"KendraQuery2"
],
"rp": "AlexReprompt"
}
]
}
================================================
FILE: .nightswatch/functional/question_bank/kendra_questions.json
================================================
{
"qna": [
{
"a": "Check out these links:",
"kendraRedirectQueryText": "alexa AND \"custom skill\"",
"type": "qna",
"qid": "Kendra.001",
"kendraRedirectQueryConfidenceThreshold": "LOW",
"q": ["Unrelated question about Kindle"]
}
]
}
================================================
FILE: .nightswatch/functional/question_bank/large_import_questions.json
================================================
{
"qna": [
{
"qid": "Translate.001",
"type": "qna",
"q": ["Can you tell me why I should use custom terminology?"],
"a": "Using custom terminology enables you to ensure your brand names aren't modified during translation."
},
{
"a": "{{#ifLang 'es'}}\n Significa mucho para mí\n{{/ifLang}}\n\n{{#defaultLang}}\n It means a lot to them\n{{/defaultLang}}",
"type": "qna",
"qid": "Translate.002",
"q": ["Why should you say mucho when talking to your Hispanic friends?"]
},
{
"qid": "Translate.003",
"type": "qna",
"q": ["Test fees translation"],
"a": "LoremipsumodorametconsectetueradipiscingelitarturientleofinibusquisqueultriciesornareutPosuerebibendumnullammaximussapienacsitegetnisiImperdietphasellusplaceratsagittissedperauctorLobortispurusgravidainsociosqucubiliametusmollisestmolestiePulvinarpotentitristiquemaximusetiamantetristiquepraesentCuraenisinamcongueascetursollicitudinfelisTacitidignissim auctor feugiatcurabiturpurusaccumsanvivamus miplateaBlanditarhoncusurnaarcudignissimsuscipit"
},
{
"qid": "Translate.004",
"type": "qna",
"q": [
"Test fees translation1",
"Test fees translation2",
"Test fees translation3",
"Test fees translation4",
"Test fees translation5",
"Test fees translation6",
"Test fees translation7",
"Test fees translation8",
"Test fees translation9",
"Test fees translation10",
"Test fees translation11",
"Test fees translation12",
"Test fees translation13",
"Test fees translation14",
"Test fees translation15",
"Test fees translation16",
"Test fees translation17",
"Test fees translation18",
"Test fees translation19",
"Test fees translation20",
"Test fees translation21",
"Test fees translation22",
"Test fees translation23",
"Test fees translation24",
"Test fees translation25",
"Test fees translation26",
"Test fees translation27",
"Test fees translation28",
"Test fees translation29",
"Test fees translation30",
"Test fees translation31",
"Test fees translation32",
"Test fees translation33",
"Test fees translation34",
"Test fees translation35",
"Test fees translation36",
"Test fees translation37", "Test fees translation38",
"Test fees translation39",
"Test fees translation40",
"Test fees translation41",
"Test fees translation42",
"Test fees translation43",
"Test fees translation44",
"Test fees translation45",
"Test fees translation46",
"Test fees translation47",
"Test fees translation48",
"Test fees translation49",
"Test fees translation50",
"Test fees translation51",
"Test fees translation52",
"Test fees translation53",
"Test fees translation54",
"Test fees translation55",
"Test fees translation56",
"Test fees translation57",
"Test fees translation58",
"Test fees translation59",
"Test fees translation60",
"Test fees translation61",
"Test fees translation62",
"Test fees translation63",
"Test fees translation64",
"Test fees translation65",
"Test fees translation66",
"Test fees translation67",
"Test fees translation68",
"Test fees translation69",
"Test fees translation70",
"Test fees translation71",
"Test fees translation72",
"Test fees translation73",
"Test fees translation74",
"Test fees translation75",
"Test fees translation76",
"Test fees translation77",
"Test fees translation78",
"Test fees translation79",
"Test fees translation80",
"Test fees translation81",
"Test fees translation82",
"Test fees translation83",
"Test fees translation84",
"Test fees translation85",
"Test fees translation86",
"Test fees translation87",
"Test fees translation88",
"Test fees translation89",
"Test fees translation90",
"Test fees translation91",
"Test fees translation92",
"Test fees translation93",
"Test fees translation94",
"Test fees translation95",
"Test fees translation96",
"Test fees translation97",
"Test fees translation98",
"Test fees translation99",
"Test fees translation100",
"Test fees translation101",
"Test fees translation102",
"Test fees translation103",
"Test fees translation104",
"Test fees translation105",
"Test fees translation106",
"Test fees translation107",
"Test fees translation108",
"Test fees translation109",
"Test fees translation110",
"Test fees translation111",
"Test fees translation112",
"Test fees translation113",
"Test fees translation114",
"Test fees translation115",
"Test fees translation116",
"Test fees translation117",
"Test fees translation118",
"Test fees translation119",
"Test fees translation120",
"Test fees translation121",
"Test fees translation122",
"Test fees translation123",
"Test fees translation124",
"Test fees translation125",
"Test fees translation126",
"Test fees translation127",
"Test fees translation128",
"Test fees translation129",
"Test fees translation130",
"Test fees translation131",
"Test fees translation132",
"Test fees translation133",
"Test fees translation134",
"Test fees translation135",
"Test fees translation136",
"Test fees translation137",
"Test fees translation138",
"Test fees translation139",
"Test fees translation140",
"Test fees translation141",
"Test fees translation142",
"Test fees translation143",
"Test fees translation144",
"Test fees translation145",
"Test fees translation146",
"Test fees translation147",
"Test fees translation148",
"Test fees translation149",
"Test fees translation150",
"Test fees translation151",
"Test fees translation152",
"Test fees translation153",
"Test fees translation154",
"Test fees translation155",
"Test fees translation156",
"Test fees translation157",
"Test fees translation158",
"Test fees translation159",
"Test fees translation160",
"Test fees translation161",
"Test fees translation162",
"Test fees translation163",
"Test fees translation164",
"Test fees translation165",
"Test fees translation166",
"Test fees translation167",
"Test fees translation168",
"Test fees translation169",
"Test fees translation170",
"Test fees translation171",
"Test fees translation172",
"Test fees translation173",
"Test fees translation174",
"Test fees translation175",
"Test fees translation176",
"Test fees translation177",
"Test fees translation178",
"Test fees translation179",
"Test fees translation180",
"Test fees translation181",
"Test fees translation182",
"Test fees translation183",
"Test fees translation184",
"Test fees translation185",
"Test fees translation186",
"Test fees translation187",
"Test fees translation188",
"Test fees translation189",
"Test fees translation190",
"Test fees translation191",
"Test fees translation192",
"Test fees translation193",
"Test fees translation194",
"Test fees translation195",
"Test fees translation196",
"Test fees translation197",
"Test fees translation198",
"Test fees translation199",
"Test fees translation200",
"Test fees translation201",
"Test fees translation202",
"Test fees translation203",
"Test fees translation204",
"Test fees translation205",
"Test fees translation206",
"Test fees translation207",
"Test fees translation208",
"Test fees translation209",
"Test fees translation210",
"Test fees translation211",
"Test fees translation212",
"Test fees translation213",
"Test fees translation214",
"Test fees translation215",
"Test fees translation216",
"Test fees translation217",
"Test fees translation218",
"Test fees translation219",
"Test fees translation220",
"Test fees translation221",
"Test fees translation222",
"Test fees translation223",
"Test fees translation224",
"Test fees translation225",
"Test fees translation226",
"Test fees translation227",
"Test fees translation228",
"Test fees translation229",
"Test fees translation230",
"Test fees translation231",
"Test fees translation232",
"Test fees translation233",
"Test fees translation234",
"Test fees translation235",
"Test fees translation236",
"Test fees translation237",
"Test fees translation238",
"Test fees translation239",
"Test fees translation240",
"Test fees translation241",
"Test fees translation242",
"Test fees translation243",
"Test fees translation244",
"Test fees translation245",
"Test fees translation246",
"Test fees translation247",
"Test fees translation248",
"Test fees translation249",
"Test fees translation250",
"Test fees translation251",
"Test fees translation252",
"Test fees translation253",
"Test fees translation254",
"Test fees translation255",
"Test fees translation256",
"Test fees translation257",
"Test fees translation258",
"Test fees translation259",
"Test fees translation260",
"Test fees translation261",
"Test fees translation262",
"Test fees translation263",
"Test fees translation264",
"Test fees translation265",
"Test fees translation266",
"Test fees translation267",
"Test fees translation268",
"Test fees translation269",
"Test fees translation270",
"Test fees translation271",
"Test fees translation272",
"Test fees translation273",
"Test fees translation274",
"Test fees translation275",
"Test fees translation276",
"Test fees translation277",
"Test fees translation278",
"Test fees translation279",
"Test fees translation280",
"Test fees translation281",
"Test fees translation282",
"Test fees translation283",
"Test fees translation284",
"Test fees translation285",
"Test fees translation286",
"Test fees translation287",
"Test fees translation288",
"Test fees translation289",
"Test fees translation290",
"Test fees translation291",
"Test fees translation292",
"Test fees translation293",
"Test fees translation294",
"Test fees translation295",
"Test fees translation296",
"Test fees translation297",
"Test fees translation298",
"Test fees translation299",
"Test fees translation300",
"Test fees translation301",
"Test fees translation302",
"Test fees translation303",
"Test fees translation304",
"Test fees translation305",
"Test fees translation306",
"Test fees translation307",
"Test fees translation308",
"Test fees translation309",
"Test fees translation310",
"Test fees translation311",
"Test fees translation312",
"Test fees translation313",
"Test fees translation314",
"Test fees translation315",
"Test fees translation316",
"Test fees translation317",
"Test fees translation318",
"Test fees translation319",
"Test fees translation320",
"Test fees translation321",
"Test fees translation322",
"Test fees translation323",
"Test fees translation324",
"Test fees translation325",
"Test fees translation326",
"Test fees translation327",
"Test fees translation328",
"Test fees translation329",
"Test fees translation330",
"Test fees translation331",
"Test fees translation332",
"Test fees translation333",
"Test fees translation334",
"Test fees translation335",
"Test fees translation336"
],
"a": "LoremipsumodorametconsectetueradipiscingelitarturientleofinibusquisqueultriciesornareutPosuerebibendumnullammaximussapienacsitegetnisiImperdietphasellusplaceratsagittissedperauctorLobortispurusgravidainsociosqucubiliametusmollisestmolestiePulvinarpotentitristiquemaximusetiamantetristiquepraesentCuraenisinamcongueascetursollicitudinfelisTacitidignissim auctor feugiatcurabiturpurusaccumsanvivamus miplateaBlanditarhoncusurnaarcudignissimsuscipit"
},
{
"qid": "Translate.005",
"type": "qna",
"q": [
"Test fees translation1",
"Test fees translation2",
"Test fees translation3",
"Test fees translation4",
"Test fees translation5",
"Test fees translation6",
"Test fees translation7",
"Test fees translation8",
"Test fees translation9",
"Test fees translation10",
"Test fees translation11",
"Test fees translation12",
"Test fees translation13",
"Test fees translation14",
"Test fees translation15",
"Test fees translation16",
"Test fees translation17",
"Test fees translation18",
"Test fees translation19",
"Test fees translation20",
"Test fees translation21",
"Test fees translation22",
"Test fees translation23",
"Test fees translation24",
"Test fees translation25",
"Test fees translation26",
"Test fees translation27",
"Test fees translation28",
"Test fees translation29",
"Test fees translation30",
"Test fees translation31",
"Test fees translation32",
"Test fees translation33",
"Test fees translation34",
"Test fees translation35",
"Test fees translation36",
"Test fees translation37", "Test fees translation38",
"Test fees translation39",
"Test fees translation40",
"Test fees translation41",
"Test fees translation42",
"Test fees translation43",
"Test fees translation44",
"Test fees translation45",
"Test fees translation46",
"Test fees translation47",
"Test fees translation48",
"Test fees translation49",
"Test fees translation50",
"Test fees translation51",
"Test fees translation52",
"Test fees translation53",
"Test fees translation54",
"Test fees translation55",
"Test fees translation56",
"Test fees translation57",
"Test fees translation58",
"Test fees translation59",
"Test fees translation60",
"Test fees translation61",
"Test fees translation62",
"Test fees translation63",
"Test fees translation64",
"Test fees translation65",
"Test fees translation66",
"Test fees translation67",
"Test fees translation68",
"Test fees translation69",
"Test fees translation70",
"Test fees translation71",
"Test fees translation72",
"Test fees translation73",
"Test fees translation74",
"Test fees translation75",
"Test fees translation76",
"Test fees translation77",
"Test fees translation78",
"Test fees translation79",
"Test fees translation80",
"Test fees translation81",
"Test fees translation82",
"Test fees translation83",
"Test fees translation84",
"Test fees translation85",
"Test fees translation86",
"Test fees translation87",
"Test fees translation88",
"Test fees translation89",
"Test fees translation90",
"Test fees translation91",
"Test fees translation92",
"Test fees translation93",
"Test fees translation94",
"Test fees translation95",
"Test fees translation96",
"Test fees translation97",
"Test fees translation98",
"Test fees translation99",
"Test fees translation100",
"Test fees translation101",
"Test fees translation102",
"Test fees translation103",
"Test fees translation104",
"Test fees translation105",
"Test fees translation106",
"Test fees translation107",
"Test fees translation108",
"Test fees translation109",
"Test fees translation110",
"Test fees translation111",
"Test fees translation112",
"Test fees translation113",
"Test fees translation114",
"Test fees translation115",
"Test fees translation116",
"Test fees translation117",
"Test fees translation118",
"Test fees translation119",
"Test fees translation120",
"Test fees translation121",
"Test fees translation122",
"Test fees translation123",
"Test fees translation124",
"Test fees translation125",
"Test fees translation126",
"Test fees translation127",
"Test fees translation128",
"Test fees translation129",
"Test fees translation130",
"Test fees translation131",
"Test fees translation132",
"Test fees translation133",
"Test fees translation134",
"Test fees translation135",
"Test fees translation136",
"Test fees translation137",
"Test fees translation138",
"Test fees translation139",
"Test fees translation140",
"Test fees translation141",
"Test fees translation142",
"Test fees translation143",
"Test fees translation144",
"Test fees translation145",
"Test fees translation146",
"Test fees translation147",
"Test fees translation148",
"Test fees translation149",
"Test fees translation150",
"Test fees translation151",
"Test fees translation152",
"Test fees translation153",
"Test fees translation154",
"Test fees translation155",
"Test fees translation156",
"Test fees translation157",
"Test fees translation158",
"Test fees translation159",
"Test fees translation160",
"Test fees translation161",
"Test fees translation162",
"Test fees translation163",
"Test fees translation164",
"Test fees translation165",
"Test fees translation166",
"Test fees translation167",
"Test fees translation168",
"Test fees translation169",
"Test fees translation170",
"Test fees translation171",
"Test fees translation172",
"Test fees translation173",
"Test fees translation174",
"Test fees translation175",
"Test fees translation176",
"Test fees translation177",
"Test fees translation178",
"Test fees translation179",
"Test fees translation180",
"Test fees translation181",
"Test fees translation182",
"Test fees translation183",
"Test fees translation184",
"Test fees translation185",
"Test fees translation186",
"Test fees translation187",
"Test fees translation188",
"Test fees translation189",
"Test fees translation190",
"Test fees translation191",
"Test fees translation192",
"Test fees translation193",
"Test fees translation194",
"Test fees translation195",
"Test fees translation196",
"Test fees translation197",
"Test fees translation198",
"Test fees translation199",
"Test fees translation200",
"Test fees translation201",
"Test fees translation202",
"Test fees translation203",
"Test fees translation204",
"Test fees translation205",
"Test fees translation206",
"Test fees translation207",
"Test fees translation208",
"Test fees translation209",
"Test fees translation210",
"Test fees translation211",
"Test fees translation212",
"Test fees translation213",
"Test fees translation214",
"Test fees translation215",
"Test fees translation216",
"Test fees translation217",
"Test fees translation218",
"Test fees translation219",
"Test fees translation220",
"Test fees translation221",
"Test fees translation222",
"Test fees translation223",
"Test fees translation224",
"Test fees translation225",
"Test fees translation226",
"Test fees translation227",
"Test fees translation228",
"Test fees translation229",
"Test fees translation230",
"Test fees translation231",
"Test fees translation232",
"Test fees translation233",
"Test fees translation234",
"Test fees translation235",
"Test fees translation236",
"Test fees translation237",
"Test fees translation238",
"Test fees translation239",
"Test fees translation240",
"Test fees translation241",
"Test fees translation242",
"Test fees translation243",
"Test fees translation244",
"Test fees translation245",
"Test fees translation246",
"Test fees translation247",
"Test fees translation248",
"Test fees translation249",
"Test fees translation250",
"Test fees translation251",
"Test fees translation252",
"Test fees translation253",
"Test fees translation254",
"Test fees translation255",
"Test fees translation256",
"Test fees translation257",
"Test fees translation258",
"Test fees translation259",
"Test fees translation260",
"Test fees translation261",
"Test fees translation262",
"Test fees translation263",
"Test fees translation264",
"Test fees translation265",
"Test fees translation266",
"Test fees translation267",
"Test fees translation268",
"Test fees translation269",
"Test fees translation270",
"Test fees translation271",
"Test fees translation272",
"Test fees translation273",
"Test fees translation274",
"Test fees translation275",
"Test fees translation276",
"Test fees translation277",
"Test fees translation278",
"Test fees translation279",
"Test fees translation280",
"Test fees translation281",
"Test fees translation282",
"Test fees translation283",
"Test fees translation284",
"Test fees translation285",
"Test fees translation286",
"Test fees translation287",
"Test fees translation288",
"Test fees translation289",
"Test fees translation290",
"Test fees translation291",
"Test fees translation292",
"Test fees translation293",
"Test fees translation294",
"Test fees translation295",
"Test fees translation296",
"Test fees translation297",
"Test fees translation298",
"Test fees translation299",
"Test fees translation300",
"Test fees translation301",
"Test fees translation302",
"Test fees translation303",
"Test fees translation304",
"Test fees translation305",
"Test fees translation306",
"Test fees translation307",
"Test fees translation308",
"Test fees translation309",
"Test fees translation310",
"Test fees translation
gitextract_l3hhubux/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── conditional_chaining.md
│ │ └── feature_request.md
│ └── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .nightswatch/
│ ├── functional/
│ │ ├── conftest.py
│ │ ├── files/
│ │ │ ├── EPCTerminology.csv
│ │ │ ├── import-fail-expected.json
│ │ │ ├── import-fail.xlsx
│ │ │ ├── import-pass-expected.json
│ │ │ ├── import-pass.xlsx
│ │ │ └── terms.csv
│ │ ├── helpers/
│ │ │ ├── __init__.py
│ │ │ ├── bot_intents/
│ │ │ │ ├── get_attribute.json
│ │ │ │ ├── greetings.json
│ │ │ │ └── set_attribute.json
│ │ │ ├── cfn_parameter_fetcher.py
│ │ │ ├── cloud_watch_client.py
│ │ │ ├── cognito_client.py
│ │ │ ├── iam_client.py
│ │ │ ├── kendra_client.py
│ │ │ ├── lex_client.py
│ │ │ ├── s3_client.py
│ │ │ ├── translate_client.py
│ │ │ ├── utils/
│ │ │ │ ├── __init__.py
│ │ │ │ └── textbox.py
│ │ │ └── website_model/
│ │ │ ├── __init__.py
│ │ │ ├── chat_page.py
│ │ │ ├── custom_terminology_page.py
│ │ │ ├── dom_operator.py
│ │ │ ├── edit_page.py
│ │ │ ├── export_page.py
│ │ │ ├── import_page.py
│ │ │ ├── kendra_page.py
│ │ │ ├── login_page.py
│ │ │ ├── menu_nav.py
│ │ │ └── settings_page.py
│ │ ├── pytest.ini
│ │ ├── question_bank/
│ │ │ ├── embeddings_questions.json
│ │ │ ├── guardrail_question.json
│ │ │ ├── import_questions.json
│ │ │ ├── import_questions_qna.json
│ │ │ ├── import_questions_slot.json
│ │ │ ├── import_questions_text.json
│ │ │ ├── kendra_questions.json
│ │ │ ├── large_import_questions.json
│ │ │ ├── llm_questions.json
│ │ │ ├── question_designer_questions.json
│ │ │ ├── routing_questions.json
│ │ │ ├── session_attribute_questions.json
│ │ │ ├── settings_questions.json
│ │ │ └── translate_questions.json
│ │ ├── test_1_login.py
│ │ ├── test_2_import.py
│ │ ├── test_embeddings.py
│ │ ├── test_export.py
│ │ ├── test_guardrails.py
│ │ ├── test_kendra.py
│ │ ├── test_knowledge_base.py
│ │ ├── test_lambda_hooks.py
│ │ ├── test_llm.py
│ │ ├── test_question_designer.py
│ │ ├── test_routing.py
│ │ ├── test_session_attribute.py
│ │ ├── test_settings.py
│ │ ├── test_translate.py
│ │ └── test_tuning.py
│ └── pyproject.toml
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.txt
├── NOTICE.txt
├── README.md
├── SECURITY.md
├── deployment/
│ ├── build-s3-dist.sh
│ └── run-unit-tests.sh
└── source/
├── .markdownlint.jsonc
├── .npmrc
├── .prettierignore
├── .prettierrc.yml
├── Makefile
├── assets/
│ ├── Makefile
│ ├── README.md
│ ├── default-utterances.json
│ └── examples/
│ ├── README.md
│ ├── documents/
│ │ ├── blog-samples-final.json
│ │ ├── blog-samples-final.txt
│ │ ├── blog-samples.json
│ │ └── blog-samples.txt
│ └── photos/
│ └── README.md
├── bin/
│ ├── .gitignore
│ ├── README.md
│ ├── URL.sh
│ ├── build.js
│ ├── check.js
│ ├── check_bucket_ownership.js
│ ├── config.js
│ ├── exports.js
│ ├── json.js
│ ├── launch.js
│ ├── license.js
│ ├── license.txt
│ ├── name.js
│ ├── update-public.sh
│ ├── upload.sh
│ └── wait.js
├── cli/
│ ├── .coveragerc
│ ├── README.md
│ ├── aws_solutions/
│ │ ├── core/
│ │ │ ├── __init__.py
│ │ │ ├── config.py
│ │ │ ├── helpers.py
│ │ │ └── logging.py
│ │ └── qnabot/
│ │ └── cli/
│ │ ├── __init__.py
│ │ ├── qnabot_cli.py
│ │ └── qnabot_cli_helper.py
│ ├── pyproject.toml
│ ├── pytest.ini
│ ├── run-pytest.py
│ └── tests/
│ ├── __init__.py
│ ├── aws_solutions/
│ │ ├── core/
│ │ │ ├── __init__.py
│ │ │ ├── test_helpers.py
│ │ │ ├── test_logging.py
│ │ │ └── test_solution_config.py
│ │ └── qnabot/
│ │ ├── __init__.py
│ │ ├── fixtures/
│ │ │ ├── cloudformation_fixtures.py
│ │ │ ├── qnabot-test-template.yaml
│ │ │ └── s3_fixtures.py
│ │ ├── test_qnabot_cli.py
│ │ └── test_qnabot_cli_helper.py
│ └── conftest.py
├── docs/
│ ├── Blogpost-BranchingNavigation.json
│ ├── Blogpost-SimpleNavigation.json
│ ├── Blogpost-SimpleNavigationSupporting.json
│ ├── LLM_Retrieval_and_generative_question_answering/
│ │ └── README.md
│ ├── PII_Detection_And_Redaction/
│ │ └── README.md
│ ├── Technical Information.md
│ ├── VPC_support/
│ │ └── README.md
│ ├── architecture.xml
│ ├── bedrock_guardrails/
│ │ └── README.md
│ ├── bedrock_knowledgebase_rag/
│ │ └── README.md
│ ├── bot_routing/
│ │ └── README.md
│ ├── client_filters.md
│ ├── connect_callback/
│ │ └── README.md
│ ├── custom_domain_name_setup/
│ │ └── README.md
│ ├── custom_terminology_guide/
│ │ ├── README.md
│ │ └── sample.csv
│ ├── excel_import/
│ │ ├── README.md
│ │ └── sample.xlsx
│ ├── handlebars/
│ │ └── README.md
│ ├── intent_slot_matching/
│ │ └── README.md
│ ├── kendra_crawler_guide/
│ │ └── README.md
│ ├── kendra_fallback/
│ │ └── README.md
│ ├── kendra_redirect/
│ │ └── README.md
│ ├── lambda_hooks/
│ │ ├── README.md
│ │ ├── lambda_hook_sdk.MD
│ │ └── q-business-lambda-hook-example/
│ │ ├── README.md
│ │ └── q-business-lambda-hook-template.yml
│ ├── llm_streaming_responses/
│ │ └── README.md
│ ├── multilanguage_support/
│ │ └── README.md
│ ├── overview/
│ │ └── README.md
│ ├── password_reset/
│ │ └── README.md
│ ├── qnabot_cli/
│ │ └── README.md
│ ├── recent_topics_lambda_hook_example/
│ │ ├── README.md
│ │ ├── recent topic settings.json
│ │ └── recent_topics_settings.json
│ ├── semantic_matching_using_LLM_embeddings/
│ │ └── README.md
│ ├── settings.md
│ ├── tuning_accuracy_guide/
│ │ └── README.md
│ ├── update_or_migrate_deployment/
│ │ └── README.md
│ ├── using_cloud9/
│ │ └── README.md
│ └── zombie.json
├── eslint.config.js
├── lambda/
│ ├── Makefile
│ ├── README.md
│ ├── aws-sdk-layer/
│ │ ├── Makefile
│ │ ├── package.json
│ │ └── sdk-config/
│ │ └── customSdkConfig.js
│ ├── cfn/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── lib/
│ │ │ ├── ApiDeployment.js
│ │ │ ├── CognitoDomain.js
│ │ │ ├── CognitoLogin.js
│ │ │ ├── CognitoRole.js
│ │ │ ├── CognitoUrl.js
│ │ │ ├── DefaultSettings.json
│ │ │ ├── ESCognitoClient.js
│ │ │ ├── LambdaVersion.js
│ │ │ ├── ModelAccess.js
│ │ │ ├── OpenSearchUpdates.js
│ │ │ ├── PostUpgradeImport.js
│ │ │ ├── PreUpgradeExport.js
│ │ │ ├── S3Lambda.js
│ │ │ ├── S3Unzip.js
│ │ │ ├── S3Version.js
│ │ │ ├── SettingsInitializer.js
│ │ │ ├── Variable.js
│ │ │ ├── base.js
│ │ │ ├── lex.js
│ │ │ └── util/
│ │ │ ├── customSdkConfig.js
│ │ │ ├── parseIntFromLexRequestObject.js
│ │ │ ├── promise.js
│ │ │ └── response.js
│ │ ├── package.json
│ │ └── test/
│ │ ├── index.fixtures.js
│ │ ├── index.test.js
│ │ └── lib/
│ │ ├── ApiDeployment.fixtures.js
│ │ ├── ApiDeployment.test.js
│ │ ├── CognitoDomain.fixtures.js
│ │ ├── CognitoDomain.test.js
│ │ ├── CognitoLogin.fixtures.js
│ │ ├── CognitoLogin.test.js
│ │ ├── CognitoRole.fixtures.js
│ │ ├── CognitoRole.test.js
│ │ ├── CognitoUrl.fixtures.js
│ │ ├── CognitoUrl.test.js
│ │ ├── ESCognitoClient.fixtures.js
│ │ ├── ESCognitoClient.test.js
│ │ ├── LambdaVersion.fixtures.js
│ │ ├── LambdaVersion.test.js
│ │ ├── ModelAccess.fixtures.js
│ │ ├── ModelAccess.test.js
│ │ ├── OpenSearchUpdates.fixtures.js
│ │ ├── OpenSearchUpdates.test.js
│ │ ├── PostUpgradeImport.fixtures.js
│ │ ├── PostUpgradeImport.test.js
│ │ ├── PreUpgradeExport.fixtures.js
│ │ ├── PreUpgradeExport.test.js
│ │ ├── S3Lambda.fixtures.js
│ │ ├── S3Lambda.test.js
│ │ ├── S3Unzip.fixtures.js
│ │ ├── S3Unzip.test.js
│ │ ├── S3Version.fixtures.js
│ │ ├── S3Version.test.js
│ │ ├── SettingsInitializer.fixtures.js
│ │ ├── SettingsInitializer.test.js
│ │ ├── Variable.fixtures.js
│ │ ├── Variable.test.js
│ │ ├── base.test.js
│ │ ├── lex.fixtures.js
│ │ ├── lex.test.js
│ │ └── util/
│ │ ├── customSdkConfig.test.js
│ │ ├── parseIntFromLexRequestObject.test.js
│ │ ├── promise.test.js
│ │ ├── response.fixtures.js
│ │ └── response.test.js
│ ├── cfn-lambda-layer/
│ │ ├── Makefile
│ │ └── package.json
│ ├── common-modules-layer/
│ │ ├── Makefile
│ │ ├── opensearch-client/
│ │ │ └── connection.js
│ │ └── package.json
│ ├── connect/
│ │ ├── Makefile
│ │ ├── flowsv2/
│ │ │ └── contactflowLexV2.json
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── package.json
│ │ ├── questions.json
│ │ └── test/
│ │ ├── contactflow.fixtures.js
│ │ └── index.test.js
│ ├── es-proxy-layer/
│ │ ├── Makefile
│ │ ├── jest.config.js
│ │ ├── lib/
│ │ │ ├── bedrock/
│ │ │ │ ├── AmazonEmbeddings.js
│ │ │ │ ├── AmazonNovaEmbeddings.js
│ │ │ │ ├── BedrockModelProviderPrototype.js
│ │ │ │ ├── CohereEmbeddings.js
│ │ │ │ ├── applyGuardrail.js
│ │ │ │ ├── bedrockAgents.js
│ │ │ │ ├── bedrockClient.js
│ │ │ │ ├── bedrockLLMProvider.js
│ │ │ │ ├── bedrockModelConstants.js
│ │ │ │ └── bedrockModels.js
│ │ │ ├── cfn.js
│ │ │ ├── cleanmetrics.js
│ │ │ ├── dialog-event/
│ │ │ │ ├── processDialogEvent.js
│ │ │ │ └── processSlots.js
│ │ │ ├── embeddings.js
│ │ │ ├── es-logging.js
│ │ │ ├── es_query.js
│ │ │ ├── esbodybuilder.js
│ │ │ ├── fulfillment-event/
│ │ │ │ ├── encryptor.js
│ │ │ │ ├── evaluateConditionalChaining.js
│ │ │ │ ├── getHit.js
│ │ │ │ ├── invokeLambda.js
│ │ │ │ ├── mergeNext.js
│ │ │ │ ├── processFulfillmentEvent.js
│ │ │ │ ├── qid.js
│ │ │ │ ├── runKendraQuery.js
│ │ │ │ ├── runLlmQa.js
│ │ │ │ ├── safeExpressionEvaluator.js
│ │ │ │ ├── updateResWithHit.js
│ │ │ │ └── utterance.js
│ │ │ ├── getConnectionId.js
│ │ │ ├── handlebars.js
│ │ │ ├── handler.js
│ │ │ ├── hits_topic_tiebreaker.js
│ │ │ ├── kendra.js
│ │ │ ├── kendraClient.js
│ │ │ ├── kendraQuery.js
│ │ │ ├── kendraRetrieve.js
│ │ │ ├── keywords.js
│ │ │ ├── llm.js
│ │ │ ├── qid.js
│ │ │ ├── query.js
│ │ │ ├── redactHelper.js
│ │ │ ├── request.js
│ │ │ ├── sanitizeOutput.js
│ │ │ ├── signS3URL.js
│ │ │ ├── supportedLanguages.js
│ │ │ ├── translate.js
│ │ │ ├── truncate.js
│ │ │ └── utterances.js
│ │ ├── package.json
│ │ └── test/
│ │ ├── applyGuardrail.test.js
│ │ ├── bedrockAgents.test.js
│ │ ├── bedrockModelConstants.test.js
│ │ ├── bedrockModels.test.js
│ │ ├── cfn.test.js
│ │ ├── dialog-event/
│ │ │ ├── processDialogEvent.fixtures.js
│ │ │ ├── processDialogEvent.test.js
│ │ │ ├── processSlots.fixtures.js
│ │ │ └── processSlots.test.js
│ │ ├── embeddings.test.js
│ │ ├── es-logging.test.js
│ │ ├── es_query.fixtures.js
│ │ ├── es_query.test.js
│ │ ├── fulfillment-event/
│ │ │ ├── evaluateConditionalChaining.test.js
│ │ │ ├── getHit.fixtures.js
│ │ │ ├── getHit.test.js
│ │ │ ├── mergeNext.test.js
│ │ │ ├── processFulfillmentEvent.fixtures.js
│ │ │ ├── processFulfillmentEvent.test.js
│ │ │ ├── runLlmQa.test.js
│ │ │ ├── safeExpressionEvaluator.test.js
│ │ │ ├── updateResWithHit.fixtures.js
│ │ │ └── updateResWithHit.test.js
│ │ ├── getConnectionId.test.js
│ │ ├── handlebars.fixtures.js
│ │ ├── handlebars.test.js
│ │ ├── kendra.fixtures.js
│ │ ├── kendra.test.js
│ │ ├── kendraQuery.fixtures.js
│ │ ├── kendraQuery.test.js
│ │ ├── kendraRetrieve.fixtures.js
│ │ ├── kendraRetrieve.test.js
│ │ ├── keywords.test.js
│ │ ├── llm.fixtures.js
│ │ ├── llm.test.js
│ │ ├── query.test.js
│ │ ├── redactHelper.test.js
│ │ ├── sanitizeOutput.test.js
│ │ ├── signS3Url.test.js
│ │ ├── translate.fixtures.js
│ │ └── translate.test.js
│ ├── export/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── createFAQ.js
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── kendraSync.js
│ │ ├── lib/
│ │ │ ├── clean.js
│ │ │ ├── join.js
│ │ │ ├── load.js
│ │ │ ├── start.js
│ │ │ └── step.js
│ │ ├── package.json
│ │ ├── parseJSON.js
│ │ └── test/
│ │ ├── createFAQ.test.js
│ │ ├── index.fixtures.js
│ │ ├── index.test.js
│ │ ├── kendraSync.test.js
│ │ ├── lib/
│ │ │ ├── clean.test.js
│ │ │ ├── join.test.js
│ │ │ ├── load.test.js
│ │ │ ├── start.test.js
│ │ │ └── step.test.js
│ │ ├── parseJSON.test.js
│ │ └── qna_FAQ.json
│ ├── fulfillment/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── lib/
│ │ │ ├── middleware/
│ │ │ │ ├── 1_parse.js
│ │ │ │ ├── 2_preprocess.js
│ │ │ │ ├── 3_query.js
│ │ │ │ ├── 4_hook.js
│ │ │ │ ├── 5_assemble.js
│ │ │ │ ├── 6_cache.js
│ │ │ │ ├── 7_userInfo.js
│ │ │ │ ├── README.md
│ │ │ │ ├── alexa.js
│ │ │ │ ├── jwt.js
│ │ │ │ ├── lex.js
│ │ │ │ ├── lexRouter.js
│ │ │ │ ├── multilanguage.js
│ │ │ │ ├── sentiment.js
│ │ │ │ ├── specialtyBotRouter.js
│ │ │ │ └── util.js
│ │ │ └── router/
│ │ │ ├── README.md
│ │ │ └── index.js
│ │ ├── package.json
│ │ └── test/
│ │ ├── alexa/
│ │ │ ├── README.md
│ │ │ ├── cancel.json
│ │ │ ├── end.json
│ │ │ ├── intent.json
│ │ │ ├── schema.json
│ │ │ └── start.json
│ │ ├── index.fixtures.js
│ │ ├── index.test.js
│ │ ├── lex/
│ │ │ ├── README.md
│ │ │ ├── index.js
│ │ │ └── schema.json
│ │ └── lib/
│ │ └── middleware/
│ │ ├── 1_parse.fixtures.js
│ │ ├── 1_parse.test.js
│ │ ├── 2_preprocess.fixtures.js
│ │ ├── 2_preprocess.test.js
│ │ ├── 3_query.fixtures.js
│ │ ├── 3_query.test.js
│ │ ├── 4_hook.test.js
│ │ ├── 5_assemble.fixtures.js
│ │ ├── 5_assemble.test.js
│ │ ├── 6_cache.test.js
│ │ ├── 7_userInfo.test.js
│ │ ├── __mocks__/
│ │ │ └── esQueryMock.js
│ │ ├── alexa.fixtures.js
│ │ ├── alexa.test.js
│ │ ├── jwt.fixtures.js
│ │ ├── jwt.test.js
│ │ ├── lex.fixtures.js
│ │ ├── lex.test.js
│ │ ├── lexRouter.fixtures.js
│ │ ├── lexRouter.test.js
│ │ ├── multilanguage.fixtures.js
│ │ ├── multilanguage.test.js
│ │ ├── sentiment.test.js
│ │ ├── specialtyBotRouter.fixtures.js
│ │ ├── specialtyBotRouter.test.js
│ │ ├── util.fixtures.js
│ │ └── util.test.js
│ ├── genesys/
│ │ ├── Makefile
│ │ ├── flowsv2/
│ │ │ └── QnABot-CallFlow.yaml
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── package.json
│ │ └── test/
│ │ ├── callflow.fixtures.yaml
│ │ └── index.test.js
│ ├── import/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── convert-xlsx.js
│ │ ├── delete_existing_content.js
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── package.json
│ │ └── test/
│ │ ├── convert-xlsx.test.js
│ │ ├── delete_existing_content.test.js
│ │ ├── import-test.xlsx
│ │ ├── index.test.js
│ │ └── lib/
│ │ └── __mocks__/
│ │ ├── embeddingsMock.js
│ │ └── requestMock.js
│ ├── js_lambda_hook_sdk/
│ │ ├── Makefile
│ │ ├── jest.config.js
│ │ ├── lambda_hook_sdk/
│ │ │ └── hooks.js
│ │ ├── package.json
│ │ └── test/
│ │ ├── hooks.fixtures.js
│ │ └── hooks.test.js
│ ├── kendra-webcrawler/
│ │ ├── .coveragerc
│ │ ├── Makefile
│ │ ├── kendra-dashboard.json
│ │ ├── kendra_webcrawler.py
│ │ ├── pyproject.toml
│ │ ├── pytest.ini
│ │ ├── role.txt
│ │ └── test/
│ │ ├── conftest.py
│ │ └── test_lambda_function.py
│ ├── kendra-webcrawler-schedule-updater/
│ │ ├── .coveragerc
│ │ ├── Makefile
│ │ ├── kendra_webcrawler_schedule_updater.py
│ │ ├── pyproject.toml
│ │ ├── pytest.ini
│ │ └── test/
│ │ ├── conftest.py
│ │ └── test_lambda_function.py
│ ├── kendra-webcrawler-status/
│ │ ├── .coveragerc
│ │ ├── Makefile
│ │ ├── kendra_webcrawler_status.py
│ │ ├── pyproject.toml
│ │ ├── pytest.ini
│ │ ├── role.txt
│ │ └── test/
│ │ ├── conftest.py
│ │ └── test_lambda_function.py
│ ├── lex-build/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── lib/
│ │ │ ├── README.md
│ │ │ ├── index.js
│ │ │ ├── lexv2bot.js
│ │ │ ├── qidsandquestions.js
│ │ │ └── statusv2.js
│ │ ├── package.json
│ │ └── test/
│ │ └── lib/
│ │ ├── __mocks__/
│ │ │ └── conMock.js
│ │ ├── es.fixtures.js
│ │ ├── index.test.js
│ │ ├── intent.fixtures.js
│ │ ├── lexv2bot.test.js
│ │ ├── qidsandquestions.test.js
│ │ └── statusv2.test.js
│ ├── lexv2-build/
│ │ ├── .coveragerc
│ │ ├── Makefile
│ │ ├── handler.py
│ │ ├── pyproject.toml
│ │ ├── pytest.ini
│ │ └── test/
│ │ ├── conftest.py
│ │ └── test_lambda_function.py
│ ├── proxy-es/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── resource.js
│ ├── q-business-lambda-hook/
│ │ ├── Makefile
│ │ └── q_business_lambda_hook.py
│ ├── qnabot-common-layer/
│ │ ├── Makefile
│ │ ├── jest.config.js
│ │ ├── package.json
│ │ ├── qnabot/
│ │ │ ├── logging.js
│ │ │ └── settings.js
│ │ └── test/
│ │ ├── logging.fixtures.js
│ │ ├── logging.test.js
│ │ ├── settings.fixtures.js
│ │ └── settings.test.js
│ ├── s3-clean/
│ │ ├── .coveragerc
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── lambda_function.py
│ │ ├── pyproject.toml
│ │ ├── pytest.ini
│ │ └── test/
│ │ ├── conftest.py
│ │ └── test_lambda_function.py
│ ├── schema/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── package.json
│ │ ├── qna.js
│ │ ├── quiz.js
│ │ ├── slottype.js
│ │ ├── test/
│ │ │ └── index.test.js
│ │ └── text.js
│ ├── solution-helper/
│ │ ├── .coveragerc
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── lambda_function.py
│ │ ├── pyproject.toml
│ │ ├── pytest.ini
│ │ └── test/
│ │ ├── conftest.py
│ │ └── test_lambda_function.py
│ ├── streaming/
│ │ ├── Makefile
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test/
│ │ └── index.test.js
│ ├── test.js
│ ├── testall/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── lib/
│ │ │ ├── clean.js
│ │ │ ├── lex.js
│ │ │ ├── load.js
│ │ │ ├── start.js
│ │ │ └── step.js
│ │ ├── package.json
│ │ └── test/
│ │ ├── index.fixtures.js
│ │ ├── index.test.js
│ │ └── lib/
│ │ ├── clean.test.js
│ │ ├── lex.fixtures.js
│ │ ├── lex.test.js
│ │ ├── load.test.js
│ │ ├── start.test.js
│ │ └── step.test.js
│ ├── translate/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── jest.config.js
│ │ ├── package.json
│ │ └── test/
│ │ ├── index.test.js
│ │ └── translate.fixtures.js
│ └── warmer/
│ ├── Makefile
│ ├── index.js
│ ├── jest.config.js
│ ├── lib/
│ │ └── index.js
│ ├── package.json
│ └── test/
│ ├── index.test.js
│ └── lib/
│ └── index.test.js
├── package.json
├── templates/
│ ├── .gitignore
│ ├── README.md
│ ├── __mocks__/
│ │ └── @smithy/
│ │ └── uuid.js
│ ├── __tests__/
│ │ └── setup.js
│ ├── dev/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── __tests__/
│ │ │ ├── __snapshots__/
│ │ │ │ ├── bucket.test.js.snap
│ │ │ │ └── dev.test.js.snap
│ │ │ ├── bucket.test.js
│ │ │ ├── dev.test.js
│ │ │ ├── masterConfig.test.js
│ │ │ ├── masterNoConfig.test.js
│ │ │ ├── mockConfigEmpty.json
│ │ │ ├── mockConfigFull.json
│ │ │ └── mockMaster.js
│ │ ├── api.js
│ │ ├── bootstrap/
│ │ │ ├── README.md
│ │ │ ├── __snapshots__/
│ │ │ │ └── index.test.js.snap
│ │ │ ├── __tests__/
│ │ │ │ ├── handler.fixtures.js
│ │ │ │ └── handler.test.js
│ │ │ ├── handler.js
│ │ │ ├── index.js
│ │ │ └── index.test.js
│ │ ├── bucket.js
│ │ ├── cognito.js
│ │ ├── lambda.js
│ │ └── master.js
│ ├── examples/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── __snapshots__/
│ │ │ └── index.test.js.snap
│ │ ├── examples/
│ │ │ ├── Makefile
│ │ │ ├── README.md
│ │ │ ├── __tests__/
│ │ │ │ └── cfn.test.js
│ │ │ ├── cfn.js
│ │ │ ├── examples/
│ │ │ │ ├── ClientFilterDemo.json
│ │ │ │ ├── ClientFilterDemo.txt
│ │ │ │ ├── ConditionalChainingDemo.json
│ │ │ │ ├── ConditionalChainingDemo.txt
│ │ │ │ ├── ConnectCallback.json
│ │ │ │ ├── ConnectCallback.txt
│ │ │ │ ├── ConnectWizardQnA.json
│ │ │ │ ├── ConnectWizardQnA.txt
│ │ │ │ ├── Embeddings.json
│ │ │ │ ├── Embeddings.txt
│ │ │ │ ├── GenesysWizardQnA.json
│ │ │ │ ├── GenesysWizardQnA.txt
│ │ │ │ ├── GreetingHook.json
│ │ │ │ ├── GreetingHook.txt
│ │ │ │ ├── PrairieLineTrailTour.json
│ │ │ │ ├── PrairieLineTrailTour.txt
│ │ │ │ ├── QnaUtility.json
│ │ │ │ ├── QnaUtility.txt
│ │ │ │ ├── RecentTopicsDemo.json
│ │ │ │ ├── RecentTopicsDemo.txt
│ │ │ │ ├── TextPassage-NurseryRhymeExamples.json
│ │ │ │ ├── TextPassage-NurseryRhymeExamples.txt
│ │ │ │ ├── guided-navigation.json
│ │ │ │ ├── guided-navigation.txt
│ │ │ │ ├── markdownSSML.json
│ │ │ │ ├── markdownSSML.txt
│ │ │ │ ├── quiz.json
│ │ │ │ ├── quiz.txt
│ │ │ │ ├── repromptDemo.json
│ │ │ │ ├── repromptDemo.txt
│ │ │ │ ├── topic.json
│ │ │ │ └── topic.txt
│ │ │ ├── index.js
│ │ │ ├── js/
│ │ │ │ ├── Quiz.js
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── Quiz.fixtures.js
│ │ │ │ │ ├── Quiz.test.js
│ │ │ │ │ └── hook.test.js
│ │ │ │ ├── hook.js
│ │ │ │ └── templates/
│ │ │ │ ├── quiz-response.hbs
│ │ │ │ └── quiz-response.md
│ │ │ ├── package.json
│ │ │ ├── py/
│ │ │ │ ├── BotBroker.py
│ │ │ │ ├── ConnectCallback.py
│ │ │ │ ├── Feedback.py
│ │ │ │ ├── Next.py
│ │ │ │ ├── Previous.py
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── conftest.py
│ │ │ │ │ ├── test_ConnectCallback.py
│ │ │ │ │ ├── test_Feedback.py
│ │ │ │ │ ├── test_Next.py
│ │ │ │ │ ├── test_Previous.py
│ │ │ │ │ └── test_hello.py
│ │ │ │ ├── hello.py
│ │ │ │ ├── pyproject.toml
│ │ │ │ └── pytest.ini
│ │ │ └── responsebots-lexv2.js
│ │ ├── extensions/
│ │ │ ├── Makefile
│ │ │ ├── README.md
│ │ │ ├── index.js
│ │ │ ├── js_lambda_hooks/
│ │ │ │ ├── CreateRecentTopicsResponse/
│ │ │ │ │ ├── CreateRecentTopicsResponse.js
│ │ │ │ │ └── package.json
│ │ │ │ └── CustomJSHook/
│ │ │ │ ├── CustomJSHook.js
│ │ │ │ ├── __tests__/
│ │ │ │ │ └── CustomJSHook.test.js
│ │ │ │ └── package.json
│ │ │ ├── py_lambda_hooks/
│ │ │ │ └── CustomPYHook/
│ │ │ │ ├── CustomPYHook.py
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── conftest.py
│ │ │ │ │ └── test_CustomPYHook.py
│ │ │ │ ├── pyproject.toml
│ │ │ │ └── pytest.ini
│ │ │ └── ui_imports/
│ │ │ ├── content/
│ │ │ │ ├── CustomHook.json
│ │ │ │ ├── CustomHook.txt
│ │ │ │ ├── IntentSlotMatching.json
│ │ │ │ ├── IntentSlotMatching.txt
│ │ │ │ ├── Language.json
│ │ │ │ └── Language.txt
│ │ │ ├── package.json
│ │ │ └── ui_import.js
│ │ ├── index.js
│ │ ├── index.test.js
│ │ └── outputs.js
│ ├── export/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── __snapshots__/
│ │ │ └── index.test.js.snap
│ │ ├── bucket.js
│ │ ├── index.js
│ │ ├── index.test.js
│ │ ├── outputs.js
│ │ └── resources.js
│ ├── import/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── UpgradeAutoImport.js
│ │ ├── __snapshots__/
│ │ │ └── index.test.js.snap
│ │ ├── bucket.js
│ │ ├── index.js
│ │ ├── index.test.js
│ │ ├── outputs.js
│ │ └── resources.js
│ ├── jest.config.js
│ ├── master/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── UpgradeAutoExport.js
│ │ ├── __snapshots__/
│ │ │ └── index.test.js.snap
│ │ ├── assets.js
│ │ ├── bucket.js
│ │ ├── cfn/
│ │ │ ├── __tests__/
│ │ │ │ ├── handler.fixtures.js
│ │ │ │ └── handler.test.js
│ │ │ ├── handler.js
│ │ │ └── index.js
│ │ ├── cognito/
│ │ │ ├── index.js
│ │ │ ├── invite.txt
│ │ │ └── style/
│ │ │ ├── README.md
│ │ │ ├── client.scss
│ │ │ ├── cognito-login.css
│ │ │ ├── designer.scss
│ │ │ ├── index.html
│ │ │ └── index.js
│ │ ├── config.js
│ │ ├── dashboard/
│ │ │ ├── README.md
│ │ │ ├── body.js
│ │ │ ├── index.js
│ │ │ ├── lambdas.js
│ │ │ ├── opensearch.js
│ │ │ └── util.js
│ │ ├── dynamodb/
│ │ │ └── index.js
│ │ ├── examples.js
│ │ ├── exportstack.js
│ │ ├── importstack.js
│ │ ├── index.js
│ │ ├── index.test.js
│ │ ├── lambda-layers.js
│ │ ├── lambda.js
│ │ ├── lex/
│ │ │ ├── README.md
│ │ │ ├── bot.js
│ │ │ ├── config.js
│ │ │ ├── fulfillment.js
│ │ │ └── index.js
│ │ ├── lex-build/
│ │ │ ├── __tests__/
│ │ │ │ ├── poll.test.js
│ │ │ │ ├── start.test.js
│ │ │ │ └── test.json
│ │ │ ├── index.js
│ │ │ ├── poll.js
│ │ │ └── start.js
│ │ ├── lexv2-build/
│ │ │ └── index.js
│ │ ├── mappings/
│ │ │ ├── anonymized-data.js
│ │ │ └── bedrock-defaults.js
│ │ ├── opensearch/
│ │ │ ├── README.md
│ │ │ ├── __tests__/
│ │ │ │ ├── handler.fixtures.js
│ │ │ │ └── handler.test.js
│ │ │ ├── es.js
│ │ │ ├── firehose.js
│ │ │ ├── handler.js
│ │ │ ├── index.js
│ │ │ ├── index_mappings.js
│ │ │ ├── index_settings.js
│ │ │ ├── info.js
│ │ │ ├── opensearch-dashboards/
│ │ │ │ ├── QnABotDashboard.json
│ │ │ │ └── README.md
│ │ │ ├── proxy.js
│ │ │ └── updates.js
│ │ ├── policies.json
│ │ ├── proxy-es.js
│ │ ├── proxy-lex/
│ │ │ ├── README.md
│ │ │ ├── handler.js
│ │ │ ├── index.js
│ │ │ ├── status.js
│ │ │ └── test.js
│ │ ├── roles.json
│ │ ├── routes/
│ │ │ ├── README.md
│ │ │ ├── bot/
│ │ │ │ ├── alexa.vm
│ │ │ │ ├── get.resp.vm
│ │ │ │ ├── get.vm
│ │ │ │ ├── index.js
│ │ │ │ ├── post.resp.vm
│ │ │ │ ├── post.vm
│ │ │ │ ├── test.js
│ │ │ │ └── utterance.get.vm
│ │ │ ├── error/
│ │ │ │ ├── error.vm
│ │ │ │ └── test.js
│ │ │ ├── examples/
│ │ │ │ ├── handler.js
│ │ │ │ ├── index.js
│ │ │ │ ├── info.vm
│ │ │ │ ├── list.vm
│ │ │ │ ├── photos.vm
│ │ │ │ └── test.js
│ │ │ ├── health/
│ │ │ │ ├── health.resp.vm
│ │ │ │ ├── health.vm
│ │ │ │ ├── index.js
│ │ │ │ └── test.js
│ │ │ ├── images.js
│ │ │ ├── index.js
│ │ │ ├── jobs/
│ │ │ │ ├── __tests__/
│ │ │ │ │ └── handler.test.js
│ │ │ │ ├── export-start.vm
│ │ │ │ ├── handler.js
│ │ │ │ ├── index.js
│ │ │ │ ├── info.vm
│ │ │ │ ├── list-export.vm
│ │ │ │ ├── list-testall.vm
│ │ │ │ ├── list.vm
│ │ │ │ ├── test.js
│ │ │ │ └── testall-start.vm
│ │ │ ├── login.js
│ │ │ ├── proxy.js
│ │ │ ├── qa/
│ │ │ │ ├── collection/
│ │ │ │ │ ├── delete.resp.vm
│ │ │ │ │ └── delete.vm
│ │ │ │ ├── index.js
│ │ │ │ ├── single/
│ │ │ │ │ ├── delete.resp.vm
│ │ │ │ │ ├── delete.vm
│ │ │ │ │ ├── get.resp.vm
│ │ │ │ │ ├── get.vm
│ │ │ │ │ ├── head.resp.vm
│ │ │ │ │ ├── head.vm
│ │ │ │ │ ├── options.vm
│ │ │ │ │ ├── put.resp.vm
│ │ │ │ │ └── put.vm
│ │ │ │ └── test.js
│ │ │ ├── root/
│ │ │ │ ├── index.js
│ │ │ │ ├── info.vm
│ │ │ │ └── test.js
│ │ │ ├── services/
│ │ │ │ ├── index.js
│ │ │ │ ├── info.vm
│ │ │ │ └── test.js
│ │ │ ├── test.js
│ │ │ └── util/
│ │ │ ├── context.js
│ │ │ ├── lambda.js
│ │ │ ├── mock.js
│ │ │ ├── options.js
│ │ │ ├── redirect.js
│ │ │ ├── resource.js
│ │ │ └── temp-test.js
│ │ ├── s3-clean/
│ │ │ └── index.js
│ │ ├── s3.js
│ │ ├── schemaLambda.js
│ │ ├── settings.js
│ │ ├── signup/
│ │ │ ├── README.md
│ │ │ ├── __tests__/
│ │ │ │ ├── message.fixtures.js
│ │ │ │ ├── message.test.js
│ │ │ │ ├── signup.fixtures.js
│ │ │ │ └── signup.test.js
│ │ │ ├── index.js
│ │ │ ├── message.js
│ │ │ └── signup.js
│ │ ├── solution-helper/
│ │ │ └── index.js
│ │ ├── streamingstack.js
│ │ ├── tstallstack.js
│ │ └── var.js
│ ├── package.json
│ ├── public/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── __tests__/
│ │ │ ├── expectedResult.js
│ │ │ ├── indexConfig.test.js
│ │ │ ├── indexNoConfig.test.js
│ │ │ ├── mockConfig.json
│ │ │ └── mockMaster.js
│ │ └── index.js
│ ├── public-vpc-support/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── __tests__/
│ │ │ ├── expectedResult.js
│ │ │ ├── indexConfig.test.js
│ │ │ ├── indexNoConfig.test.js
│ │ │ ├── mockConfig.json
│ │ │ └── mockMaster.js
│ │ └── index.js
│ ├── streaming/
│ │ ├── Makefile
│ │ ├── index.js
│ │ ├── outputs.js
│ │ └── resources.js
│ ├── testall/
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── __snapshots__/
│ │ │ └── index.test.js.snap
│ │ ├── bucket.js
│ │ ├── index.js
│ │ ├── index.test.js
│ │ ├── outputs.js
│ │ └── resources.js
│ └── util.js
├── utility_scripts/
│ ├── README.md
│ ├── configureAlerts.py
│ ├── configureCMK.py
│ ├── count_user_interactions.js
│ ├── create_kendra_faq_resources.js
│ ├── csv2json_converter/
│ │ ├── CSV2JSON_README.md
│ │ ├── css/
│ │ │ └── qnabot_csv2json_converter.css
│ │ ├── js/
│ │ │ ├── csvToArray.v2.1.js
│ │ │ └── qnabot_csv2json_converter.js
│ │ ├── qnabot_csv2json_converter.html
│ │ └── sample.csv
│ ├── migration.md
│ └── validate-conditional-chaining.js
└── website/
├── .babelrc
├── .gitignore
├── Makefile
├── README.md
├── __tests__/
│ ├── admin.spec.js
│ ├── admin.test.js
│ ├── client.spec.js
│ ├── client.test.js
│ ├── components/
│ │ ├── alexa/
│ │ │ └── index.spec.js
│ │ ├── connect/
│ │ │ └── index.spec.js
│ │ ├── customTranslate.spec.js
│ │ ├── designer/
│ │ │ ├── add.spec.js
│ │ │ ├── addSetting.spec.js
│ │ │ ├── alexa.spec.js
│ │ │ ├── delete.spec.js
│ │ │ ├── display.spec.js
│ │ │ ├── edit.spec.js
│ │ │ ├── empty.test.js
│ │ │ ├── event-bus.test.js
│ │ │ ├── index.spec.js
│ │ │ ├── input.spec.js
│ │ │ ├── menu-questions.spec.js
│ │ │ ├── menu-test.spec.js
│ │ │ ├── qa.spec.js
│ │ │ ├── rebuild.spec.js
│ │ │ └── synckendra.spec.js
│ │ ├── export.spec.js
│ │ ├── genesys/
│ │ │ └── index.spec.js
│ │ ├── hooks/
│ │ │ └── index.spec.js
│ │ ├── import.spec.js
│ │ ├── kendraIndex.spec.js
│ │ └── settings.spec.js
│ ├── lib/
│ │ ├── client-auth.test.js
│ │ ├── index.test.js
│ │ ├── router.test.js
│ │ └── store/
│ │ ├── api/
│ │ │ └── actions/
│ │ │ ├── connect.test.js
│ │ │ ├── export.test.js
│ │ │ ├── genesys.test.js
│ │ │ ├── import.test.js
│ │ │ ├── index.test.js
│ │ │ ├── kendraIndex.test.js
│ │ │ ├── mockedContext.js
│ │ │ ├── settings.test.js
│ │ │ ├── testall.test.js
│ │ │ └── util.test.js
│ │ ├── data/
│ │ │ ├── actions/
│ │ │ │ ├── add.test.js
│ │ │ │ ├── delete.test.js
│ │ │ │ ├── get.test.js
│ │ │ │ ├── up-download.test.js
│ │ │ │ └── util.test.js
│ │ │ ├── getters.test.js
│ │ │ └── mutations.test.js
│ │ ├── page/
│ │ │ ├── actions.test.js
│ │ │ ├── getters.test.js
│ │ │ ├── mutations.test.js
│ │ │ └── util.test.js
│ │ └── user/
│ │ ├── actions.test.js
│ │ ├── getters.test.js
│ │ ├── index.test.js
│ │ └── mutations.test.js
│ ├── resolver.js
│ ├── styleMock.js
│ └── test.test.js
├── assets/
│ └── zombie.json
├── config/
│ ├── base.config.js
│ ├── dev.config.js
│ ├── prod.config.js
│ ├── test.config.js
│ └── webpack.config.js
├── entry.js
├── html/
│ ├── admin.pug
│ ├── client.pug
│ └── test.ejs
├── js/
│ ├── admin.js
│ ├── admin.vue
│ ├── browser-check.js
│ ├── capability/
│ │ └── util.js
│ ├── client.js
│ ├── client.vue
│ ├── components/
│ │ ├── alexa/
│ │ │ ├── index.vue
│ │ │ └── steps.js
│ │ ├── connect/
│ │ │ ├── index.vue
│ │ │ └── steps.js
│ │ ├── customTranslate.vue
│ │ ├── designer/
│ │ │ ├── add.vue
│ │ │ ├── addSetting.vue
│ │ │ ├── alexa.vue
│ │ │ ├── delete.vue
│ │ │ ├── display.vue
│ │ │ ├── edit.vue
│ │ │ ├── empty.js
│ │ │ ├── event-bus.js
│ │ │ ├── index.vue
│ │ │ ├── input.vue
│ │ │ ├── menu-questions.vue
│ │ │ ├── menu-test.vue
│ │ │ ├── menu-testall.vue
│ │ │ ├── modal.vue
│ │ │ ├── qa.vue
│ │ │ ├── rebuild.vue
│ │ │ └── synckendra.vue
│ │ ├── export.vue
│ │ ├── genesys/
│ │ │ ├── index.vue
│ │ │ └── steps.js
│ │ ├── hooks/
│ │ │ ├── codejs.txt
│ │ │ ├── codepy.txt
│ │ │ ├── example.js
│ │ │ ├── index.vue
│ │ │ └── steps.js
│ │ ├── import.vue
│ │ ├── kendraIndex.vue
│ │ ├── loading.vue
│ │ └── settings.vue
│ ├── lib/
│ │ ├── client-auth.js
│ │ ├── index.js
│ │ ├── router.js
│ │ ├── store/
│ │ │ ├── actions.js
│ │ │ ├── api/
│ │ │ │ ├── actions/
│ │ │ │ │ ├── connect.js
│ │ │ │ │ ├── export.js
│ │ │ │ │ ├── genesys.js
│ │ │ │ │ ├── import.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── kendraIndex.js
│ │ │ │ │ ├── settings.js
│ │ │ │ │ ├── testall.js
│ │ │ │ │ └── tmp.js
│ │ │ │ ├── card-schema.json
│ │ │ │ ├── index.js
│ │ │ │ └── schema.json
│ │ │ ├── data/
│ │ │ │ ├── actions/
│ │ │ │ │ ├── add.js
│ │ │ │ │ ├── delete.js
│ │ │ │ │ ├── get.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── schema.json
│ │ │ │ │ ├── up-download.js
│ │ │ │ │ └── util.js
│ │ │ │ ├── getters.js
│ │ │ │ ├── index.js
│ │ │ │ └── mutations.js
│ │ │ ├── getters.js
│ │ │ ├── index.js
│ │ │ ├── mutations.js
│ │ │ ├── page/
│ │ │ │ ├── actions.js
│ │ │ │ ├── getters.js
│ │ │ │ ├── index.js
│ │ │ │ ├── mutations.js
│ │ │ │ └── util.js
│ │ │ └── user/
│ │ │ ├── actions.js
│ │ │ ├── getters.js
│ │ │ ├── index.js
│ │ │ ├── mutations.js
│ │ │ └── schema.json
│ │ └── validator.js
│ └── test.js
├── style/
│ └── app.styl
└── styles/
├── app.css
├── fonts/
│ └── material-icons.css
├── pure-min.css
└── vuetify-min.css
SYMBOL INDEX (1487 symbols across 269 files)
FILE: .nightswatch/functional/conftest.py
function get_password (line 24) | def get_password() -> str:
function region (line 47) | def region() -> str:
function stack_name (line 51) | def stack_name() -> str:
function username (line 55) | def username() -> str:
function email (line 61) | def email() -> str:
function temporary_password (line 66) | def temporary_password() -> str:
function password (line 70) | def password() -> str:
function languages (line 76) | def languages() -> list['str']:
function param_fetcher (line 80) | def param_fetcher(region: str, stack_name: str) -> ParameterFetcher:
function kendra_client (line 84) | def kendra_client(region: str, param_fetcher: ParameterFetcher) -> Kendr...
function lex_client (line 88) | def lex_client(region: str) -> LexClient:
function translate_client (line 92) | def translate_client(region: str) -> TranslateClient:
function iam_client (line 96) | def iam_client(region: str) -> IamClient:
function s3_client (line 100) | def s3_client(region: str) -> None:
function app_version (line 104) | def app_version(param_fetcher: ParameterFetcher) -> str:
function skip_if_version_less_than (line 109) | def skip_if_version_less_than(request, app_version):
function cw_client (line 117) | def cw_client(region: str, param_fetcher: ParameterFetcher) -> CloudWatc...
function dom_operator (line 123) | def dom_operator():
function invalid_designer_login (line 129) | def invalid_designer_login(dom_operator: DomOperator, param_fetcher: Par...
function designer_login (line 136) | def designer_login(dom_operator: DomOperator, param_fetcher: ParameterFe...
function client_login (line 142) | def client_login(dom_operator: DomOperator, param_fetcher: ParameterFetc...
function invalid_client_login (line 148) | def invalid_client_login(dom_operator: DomOperator, param_fetcher: Param...
function lambda_hook_example_arn (line 155) | def lambda_hook_example_arn(dom_operator: DomOperator, param_fetcher: Pa...
function log_timestamps (line 161) | def log_timestamps(request):
function kendra_is_enabled (line 167) | def kendra_is_enabled(param_fetcher: ParameterFetcher):
function skip_kendra (line 172) | def skip_kendra(request, kendra_is_enabled):
function knowledge_base_is_enabled (line 179) | def knowledge_base_is_enabled(param_fetcher: ParameterFetcher):
function skip_knowledge_base (line 183) | def skip_knowledge_base(request, knowledge_base_is_enabled):
function llm_is_enabled (line 190) | def llm_is_enabled(param_fetcher: ParameterFetcher):
function skip_llm (line 194) | def skip_llm(request, llm_is_enabled):
function embeddings_is_enabled (line 201) | def embeddings_is_enabled(param_fetcher: ParameterFetcher):
function skip_embeddings (line 205) | def skip_embeddings(request, embeddings_is_enabled):
function knowledge_base_model (line 213) | def knowledge_base_model(param_fetcher: ParameterFetcher):
function content_designer_output_bucket_name (line 217) | def content_designer_output_bucket_name(param_fetcher: ParameterFetcher):
FILE: .nightswatch/functional/helpers/cfn_parameter_fetcher.py
class ParameterFetcher (line 11) | class ParameterFetcher:
method __init__ (line 17) | def __init__(self, region: str, stack_name: str) -> None:
method get_user_pool_id (line 35) | def get_user_pool_id(self) -> Optional[str]:
method __get_cfn_param (line 62) | def __get_cfn_param(self, key: str) -> Optional[str]:
method __get_stack_description (line 81) | def __get_stack_description(self) -> Optional[str]:
method __get_resource_name_from_logical_id (line 94) | def __get_resource_name_from_logical_id(self, logical_id: str) -> Opti...
method __get_stack_outputs (line 108) | def __get_stack_outputs(self, key: str) -> Optional[str]:
method get_kendra_webpage_index (line 122) | def get_kendra_webpage_index(self) -> Optional[str]:
method get_kendra_faq_index (line 133) | def get_kendra_faq_index(self) -> Optional[str]:
method get_bedrock_knowledge_base_id (line 144) | def get_bedrock_knowledge_base_id(self) -> Optional[str]:
method get_designer_client_id (line 156) | def get_designer_client_id(self) -> Optional[str]:
method get_designer_url (line 172) | def get_designer_url(self) -> Optional[str]:
method get_client_url (line 182) | def get_client_url(self) -> Optional[str]:
method kendra_is_enabled (line 192) | def kendra_is_enabled(self) -> bool:
method bedrock_knowledge_base_is_enabled (line 203) | def bedrock_knowledge_base_is_enabled(self) -> bool:
method llm_is_enabled (line 214) | def llm_is_enabled(self) -> bool:
method embeddings_is_enabled (line 225) | def embeddings_is_enabled(self) -> bool:
method get_fulfillment_lambda_name (line 236) | def get_fulfillment_lambda_name(self) -> str:
method get_deployment_version (line 246) | def get_deployment_version(self) -> str:
method get_lambda_hook_example_arn (line 258) | def get_lambda_hook_example_arn(self) -> str:
method get_stack_id (line 271) | def get_stack_id(self) -> Optional[str]:
method get_bedrock_knowledge_base_model (line 285) | def get_bedrock_knowledge_base_model(self) -> Optional[str]:
method get_content_designer_output_bucket_name (line 297) | def get_content_designer_output_bucket_name(self) -> Optional[str]:
FILE: .nightswatch/functional/helpers/cloud_watch_client.py
class CloudWatchClient (line 11) | class CloudWatchClient:
method __init__ (line 16) | def __init__(self, region: str, stack_id: str, stack_name: str):
method __get_logs (line 27) | def __get_logs(self, log_group_name: str, start_time: int, filter_patt...
method print_logs (line 45) | def print_logs(self, log_group_name: str, filter_pattern: str='') -> d...
method print_fulfillment_lambda_logs (line 59) | def print_fulfillment_lambda_logs(self, filter_pattern: str='?TypeErro...
FILE: .nightswatch/functional/helpers/cognito_client.py
class CognitoClient (line 10) | class CognitoClient:
method __init__ (line 16) | def __init__(self, region: str, user_pool_id: str, client_id: str) -> ...
method create_admin_user (line 33) | def create_admin_user(self, username: str, temporary_password: str, em...
method delete_admin_user (line 69) | def delete_admin_user(self, username: str) -> None:
method create_admin_and_set_password (line 84) | def create_admin_and_set_password(self, username: str, temporary_passw...
FILE: .nightswatch/functional/helpers/iam_client.py
class IamClient (line 9) | class IamClient:
method __init__ (line 15) | def __init__(self, region: str) -> None:
method create_role (line 29) | def create_role(self, role_name: str, trust_relationship: dict) -> dict:
method attach_policy (line 47) | def attach_policy(self, policy_arn: str, role_name: str) -> dict:
method create_lexv2_role (line 65) | def create_lexv2_role(self, bot_name) -> str:
method delete_role_if_exists (line 100) | def delete_role_if_exists(self, role_name: str) -> None:
FILE: .nightswatch/functional/helpers/kendra_client.py
class KendraClient (line 8) | class KendraClient:
method __init__ (line 14) | def __init__(self, region: str, faq_index: str, webpage_index: str) ->...
method list_faqs (line 29) | def list_faqs(self) -> dict:
method delete_faq_by_id (line 39) | def delete_faq_by_id(self, id: str) -> dict:
method list_data_sources (line 54) | def list_data_sources(self) -> dict:
method query (line 64) | def query(self, query: str) -> dict:
FILE: .nightswatch/functional/helpers/lex_client.py
class LexClient (line 12) | class LexClient:
method __init__ (line 23) | def __init__(self, region: str) -> None:
method __get_bot_id_version (line 33) | def __get_bot_id_version(self, bot_name) -> tuple:
method __list_slot_type_names (line 76) | def __list_slot_type_names(self, id: str, version: str, locale: str) -...
method bot_slot_type_names_exist_for_all_locales (line 97) | def bot_slot_type_names_exist_for_all_locales(self, bot_name: str, slo...
method bot_slot_type_names_do_not_exist_for_all_locales (line 114) | def bot_slot_type_names_do_not_exist_for_all_locales(self, bot_name: s...
method create_test_bot (line 135) | def create_test_bot(self, bot_name: str, role_arn: str, intent_files: ...
method create_bot (line 164) | def create_bot(self, bot_name: str, role_arn: str) -> str:
method create_bot_locales (line 200) | def create_bot_locales(self, bot_id: str, bot_version: str, locales: l...
method build_bot_locales (line 225) | def build_bot_locales(self, bot_id: str, bot_version: str, locales: li...
method delete_bot_if_exists (line 249) | def delete_bot_if_exists(self, bot_name: str) -> None:
method create_intent (line 275) | def create_intent(self, bot_id: str, bot_version: str, intent: dict) -...
method find_bot_id_from_bot_name (line 294) | def find_bot_id_from_bot_name(self, bot_name: str) -> str:
method check_bot_exists (line 324) | def check_bot_exists(self, bot_name: str) -> bool:
FILE: .nightswatch/functional/helpers/s3_client.py
class S3Client (line 9) | class S3Client:
method __init__ (line 15) | def __init__(self, region: str) -> None:
method get_file_versions_count (line 29) | def get_file_versions_count(self, bucket_name, file_prefix):
FILE: .nightswatch/functional/helpers/translate_client.py
class TranslateClient (line 11) | class TranslateClient:
method __init__ (line 15) | def __init__(self, region: str) -> None:
method __remove_non_ascii (line 24) | def __remove_non_ascii(self, a_str: str) -> str:
method list_terminologies (line 43) | def list_terminologies(self) -> list[str]:
method has_terminology (line 56) | def has_terminology(self, name: str) -> bool:
method delete_terminology (line 69) | def delete_terminology(self, name: str):
method delete_all_terminologies (line 80) | def delete_all_terminologies(self):
method translate (line 91) | def translate(self, text: str, target_language: str) -> str:
FILE: .nightswatch/functional/helpers/utils/textbox.py
class Textbox (line 9) | class Textbox:
method __init__ (line 19) | def __init__(self, element) -> None:
method __send_keys (line 29) | def __send_keys(self, keys):
method get_value (line 39) | def get_value(self) -> str:
method set_value (line 49) | def set_value(self, value):
FILE: .nightswatch/functional/helpers/website_model/chat_page.py
class ChatPage (line 18) | class ChatPage:
method __init__ (line 29) | def __init__(self, operator: DomOperator) -> None:
method __wait_to_load (line 42) | def __wait_to_load(self):
method __wait_for_message_response (line 49) | def __wait_for_message_response(self, message):
method select_text_input (line 56) | def select_text_input(self):
method send_message (line 65) | def send_message(self, message):
method get_messages (line 77) | def get_messages(self) -> str:
method get_last_message_element (line 87) | def get_last_message_element(self):
method get_last_message_text (line 95) | def get_last_message_text(self) -> str:
method has_element_with_xpath (line 103) | def has_element_with_xpath(self, xpath) -> str:
method select_locale (line 113) | def select_locale(self, locale: str):
method send_positive_feedback (line 125) | def send_positive_feedback(self):
FILE: .nightswatch/functional/helpers/website_model/custom_terminology_page.py
class CustomTerminologyPage (line 10) | class CustomTerminologyPage:
method __init__ (line 20) | def __init__(self, operator: DomOperator) -> None:
method upload_file (line 29) | def upload_file(self, file):
FILE: .nightswatch/functional/helpers/website_model/dom_operator.py
class DomOperator (line 19) | class DomOperator():
method __new__ (line 27) | def __new__(cls):
method __init__ (line 36) | def __init__(self) -> None:
method get_url (line 56) | def get_url(self, url):
method get_current_url (line 65) | def get_current_url(self) -> str:
method set_window_size (line 74) | def set_window_size(self, x, y):
method get_title (line 84) | def get_title(self) -> str:
method refresh_browser (line 93) | def refresh_browser(self) -> None:
method element_exists_by_id (line 99) | def element_exists_by_id(self, id, wait:int=5) -> bool:
method element_exists_by_xpath (line 116) | def element_exists_by_xpath(self, xpath, wait:int=3) -> bool:
method select_id (line 133) | def select_id(self, id: str, wait:int=3, click:bool=False):
method click_element_by_id (line 151) | def click_element_by_id(self, id: str, wait:int=0):
method select_css (line 164) | def select_css(self, css_selector: str, wait:int=0, click:bool=False):
method select_name (line 182) | def select_name(self, name: str, wait:int=0, click:bool=False):
method select_xpath (line 199) | def select_xpath(self, xpath: str, wait:int=0, click:bool=False):
method wait_for_element_attribute (line 216) | def wait_for_element_attribute(self, id: str, attribute: str, value: s...
method wait_for_element_by_id (line 232) | def wait_for_element_by_id(self, id: str, delay: int = 10):
method wait_for_element_by_xpath (line 246) | def wait_for_element_by_xpath(self, xpath: str, delay: int = 10):
method wait_for_element_by_id_text (line 260) | def wait_for_element_by_id_text(self, id: str, text: str, delay: int =...
method wait_for_element_by_xpath_text (line 275) | def wait_for_element_by_xpath_text(self, xpath: str, text: str, delay:...
method switch_windows (line 290) | def switch_windows(self):
method end_session (line 305) | def end_session(self):
FILE: .nightswatch/functional/helpers/website_model/edit_page.py
class EditPage (line 114) | class EditPage:
method __init__ (line 128) | def __init__(self, operator: DomOperator) -> None:
method __wait_to_load (line 141) | def __wait_to_load(self):
method refresh_questions (line 150) | def refresh_questions(self):
method add_question (line 159) | def add_question(self, qid: str, type: str, q: list[str]=[], a: str=''...
method __add_qna_lambda_hook (line 187) | def __add_qna_lambda_hook(self, l, l_args):
method __add_qna_slot (line 199) | def __add_qna_slot(self, index, slot):
method __add_qna_card (line 223) | def __add_qna_card(self, r, type: str='qna'):
method __add_qna_question (line 248) | def __add_qna_question(self, q: list[str], a: str, l: str='', args: st...
method __add_quiz_question (line 324) | def __add_quiz_question(self, question: str, correctAnswers: list[str]...
method __add_slot_question (line 351) | def __add_slot_question(self, descr: str='', slotTypeValues: list[dict...
method __add_text_question (line 373) | def __add_text_question(self, passage):
method check_question_exists_by_qid (line 383) | def check_question_exists_by_qid(self, qid: str) -> bool:
method edit_question_by_qid (line 391) | def edit_question_by_qid(self, qid: str, type: str, q: list[str]=[], a...
method match_question_field_values (line 417) | def match_question_field_values(
method delete_question_by_qid (line 701) | def delete_question_by_qid(self, qid: str):
method select_question_by_qid (line 721) | def select_question_by_qid(self, qid: str, column: int):
method select_question_by_row_and_column (line 737) | def select_question_by_row_and_column(self, row: int, column: int):
method select_sub_menu (line 754) | def select_sub_menu(self) -> None:
method rebuild_lex (line 761) | def rebuild_lex(self) -> str:
method sync_kendra_faq (line 774) | def sync_kendra_faq(self):
method select_test_tab (line 788) | def select_test_tab(self):
method select_test_all_tab (line 795) | def select_test_all_tab(self):
method execute_test_query (line 802) | def execute_test_query(self, query: str) -> None:
method generate_test_report (line 810) | def generate_test_report(self) -> WebElement:
FILE: .nightswatch/functional/helpers/website_model/export_page.py
class ExportPage (line 14) | class ExportPage:
method __init__ (line 23) | def __init__(self, operator: DomOperator) -> None:
method __set_filename (line 33) | def __set_filename(self, filename: str):
method __set_filter (line 44) | def __set_filter(self, filter: str):
method generate_export (line 55) | def generate_export(self, filename: str, filter: str):
FILE: .nightswatch/functional/helpers/website_model/import_page.py
class ImportPage (line 16) | class ImportPage:
method __init__ (line 25) | def __init__(self, operator: DomOperator) -> None:
method __wait_to_load (line 36) | def __wait_to_load(self):
method __delete_existing_import_file_if_exists (line 44) | def __delete_existing_import_file_if_exists(self, file_name: str) -> N...
method expand_examples (line 57) | def expand_examples(self) -> None:
method select_example (line 65) | def select_example(self, item: str) -> None:
method import_file (line 75) | def import_file(self, file: str) -> None:
method get_import_file_error (line 95) | def get_import_file_error(self) -> None:
method import_blog_examples (line 102) | def import_blog_examples(self) -> None:
method import_language (line 111) | def import_language(self) -> None:
method import_greeting_hook (line 120) | def import_greeting_hook(self) -> None:
FILE: .nightswatch/functional/helpers/website_model/kendra_page.py
class KendraPage (line 19) | class KendraPage:
method __init__ (line 28) | def __init__(self, operator: DomOperator) -> None:
method __wait_to_load (line 39) | def __wait_to_load(self):
method index (line 47) | def index(self) -> None:
method get_crawling_status (line 62) | def get_crawling_status(self) -> None:
FILE: .nightswatch/functional/helpers/website_model/login_page.py
class LoginPage (line 16) | class LoginPage:
method __init__ (line 27) | def __init__(self, operator: DomOperator, url) -> None:
method __is_client (line 39) | def __is_client(self):
method login (line 49) | def login(self, username, password) -> str:
FILE: .nightswatch/functional/helpers/website_model/menu_nav.py
class MenuNav (line 30) | class MenuNav:
method __init__ (line 40) | def __init__(self, operator: DomOperator) -> None:
method select_menu (line 50) | def select_menu(self) -> None:
method __from_menu_select_item (line 55) | def __from_menu_select_item(self, item: str) -> None:
method logout (line 65) | def logout(self) -> LoginPage:
method open_import_page (line 70) | def open_import_page(self) -> ImportPage:
method open_export_page (line 77) | def open_export_page(self) -> ExportPage:
method open_edit_page (line 84) | def open_edit_page(self) -> EditPage:
method open_settings_page (line 92) | def open_settings_page(self) -> SettingsPage:
method open_kendra_page (line 99) | def open_kendra_page(self) -> KendraPage:
method open_custom_terminology (line 106) | def open_custom_terminology(self) -> CustomTerminologyPage:
method open_chat_page (line 113) | def open_chat_page(self) -> ChatPage:
method open_testall_page (line 122) | def open_testall_page(self) -> None:
FILE: .nightswatch/functional/helpers/website_model/settings_page.py
class SettingsPage (line 74) | class SettingsPage:
method __init__ (line 84) | def __init__(self, operator: DomOperator) -> None:
method save_settings (line 94) | def save_settings(self) -> str:
method reset_settings (line 106) | def reset_settings(self) -> str:
method select_setting_by_label (line 112) | def select_setting_by_label(self, label: str):
method __set_element_value (line 125) | def __set_element_value(self, element, value):
method __get_element_value (line 137) | def __get_element_value(self, element) -> str:
method customize_empty_message (line 150) | def customize_empty_message(self, message) -> str:
method enable_debug_response (line 165) | def enable_debug_response(self) -> str:
method enable_multi_language_support (line 178) | def enable_multi_language_support(self) -> str:
method enable_kendra (line 190) | def enable_kendra(self, indexer_url: str, depth: int=2, mode: str='sub...
method enable_kendra_fallback (line 225) | def enable_kendra_fallback(self) -> str:
method disable_kendra_fallback (line 238) | def disable_kendra_fallback(self) -> str:
method enable_embeddings (line 251) | def enable_embeddings(self) -> str:
method disable_embeddings (line 264) | def disable_embeddings(self) -> str:
method enable_llm (line 276) | def enable_llm(self) -> str:
method disable_llm (line 307) | def disable_llm(self) -> str:
method disable_llm_disambiguation (line 335) | def disable_llm_disambiguation(self):
method enable_bedrock_guardrail (line 341) | def enable_bedrock_guardrail(self, region, guardrail_identifier, guard...
method enable_custom_terminology (line 393) | def enable_custom_terminology(self) -> str:
method enable_filter (line 405) | def enable_filter(self) -> str:
method disable_filter (line 417) | def disable_filter(self) -> str:
method set_match_criteria (line 429) | def set_match_criteria(self, criteria: str) -> str:
method get_no_hits_response (line 444) | def get_no_hits_response(self) -> str:
method set_pre_processing_lambda (line 455) | def set_pre_processing_lambda(self, l: str) -> str:
method set_post_processing_lambda (line 471) | def set_post_processing_lambda(self, l: str) -> str:
method disable_kb_prompt (line 486) | def disable_kb_prompt(self) -> str:
method enable_kb_advanced (line 497) | def enable_kb_advanced(self, knowledge_base_model) -> str:
method expand_all_subgroups (line 520) | def expand_all_subgroups(self) -> None:
FILE: .nightswatch/functional/test_1_login.py
class TestLogin (line 16) | class TestLogin:
method test_admin_user_creation (line 19) | def test_admin_user_creation(self, region: str, param_fetcher: Paramet...
method test_invalid_designer_login (line 29) | def test_invalid_designer_login(self, invalid_designer_login):
method test_designer_login (line 37) | def test_designer_login(self, designer_login):
method test_designer_logout (line 44) | def test_designer_logout(self, designer_login, dom_operator: DomOperat...
method test_client_login (line 60) | def test_client_login(self, client_login, dom_operator: DomOperator):
method test_invalid_client_login (line 69) | def test_invalid_client_login(self, invalid_client_login):
method test_test_all_before_import (line 77) | def test_test_all_before_import(self, designer_login, dom_operator: Do...
FILE: .nightswatch/functional/test_2_import.py
class TestImport (line 13) | class TestImport:
method test_setup (line 15) | def test_setup(self, designer_login, dom_operator: DomOperator):
method test_designer_import_questions (line 24) | def test_designer_import_questions(self, designer_login, dom_operator:...
method test_designer_import_questions_json (line 36) | def test_designer_import_questions_json(self, designer_login, dom_oper...
method test_designer_import_questions_xlsx (line 60) | def test_designer_import_questions_xlsx(self, designer_login, dom_oper...
method test_designer_import_questions_xlsx_fail (line 90) | def test_designer_import_questions_xlsx_fail(self, designer_login, dom...
method test_designer_import_questions_qna (line 111) | def test_designer_import_questions_qna(self, designer_login, dom_opera...
method test_designer_import_questions_fail (line 135) | def test_designer_import_questions_fail(self, designer_login, dom_oper...
method test_designer_import_questions_quiz (line 155) | def test_designer_import_questions_quiz(self, designer_login, dom_oper...
method test_designer_import_questions_slot (line 158) | def test_designer_import_questions_slot(self, designer_login, dom_oper...
method test_designer_import_questions_text (line 182) | def test_designer_import_questions_text(self, designer_login, dom_oper...
FILE: .nightswatch/functional/test_embeddings.py
class TestEmbeddings (line 18) | class TestEmbeddings:
method loaded_questions (line 21) | def loaded_questions(self) -> list[dict]:
method __create_question (line 27) | def __create_question(self, question: dict, edit_page):
method __get_question_by_qid (line 33) | def __get_question_by_qid(self, qid, loaded_questions: list[dict]) -> ...
method test_setup (line 36) | def test_setup(self, designer_login, dom_operator: DomOperator):
method test_semantic_matching (line 48) | def test_semantic_matching(self, designer_login, loaded_questions: lis...
FILE: .nightswatch/functional/test_export.py
class TestExport (line 11) | class TestExport:
method test_designer_export_questions (line 14) | def test_designer_export_questions(self, designer_login, dom_operator:...
FILE: .nightswatch/functional/test_guardrails.py
class TestGuardrails (line 30) | class TestGuardrails:
method loaded_questions (line 33) | def loaded_questions(self) -> list[dict]:
method __create_question (line 39) | def __create_question(self, question: dict, edit_page):
method __get_question_by_qid (line 45) | def __get_question_by_qid(self, qid, loaded_questions: list[dict]) -> ...
method test_setup (line 48) | def test_setup(self, designer_login, dom_operator: DomOperator, loaded...
method test_preprocess_guardrail (line 66) | def test_preprocess_guardrail(self, designer_login, dom_operator: DomO...
method test_postprocess_guardrail (line 85) | def test_postprocess_guardrail(self, designer_login, dom_operator: Dom...
FILE: .nightswatch/functional/test_kendra.py
class TestKendra (line 27) | class TestKendra:
method loaded_questions (line 30) | def loaded_questions(self) -> list[dict]:
method __create_question (line 36) | def __create_question(self, question: dict, edit_page):
method __get_question_by_qid (line 42) | def __get_question_by_qid(self, qid, loaded_questions: list[dict]) -> ...
method test_setup (line 45) | def test_setup(self, designer_login, dom_operator: DomOperator):
method test_sync_kendra_faq (line 58) | def test_sync_kendra_faq(self, designer_login, dom_operator: DomOperat...
method test_kendra_service_faq (line 67) | def test_kendra_service_faq(self, kendra_client: KendraClient):
method test_delete_kendra_faq (line 79) | def test_delete_kendra_faq(self, kendra_client: KendraClient):
method test_start_crawling (line 92) | def test_start_crawling(self, designer_login, dom_operator: DomOperator):
method test_kendra_data_sources_status (line 116) | def test_kendra_data_sources_status(self, kendra_client: KendraClient):
method test_kendra_data_sources_results (line 137) | def test_kendra_data_sources_results(self, kendra_client: KendraClient):
method test_kendra_fallback (line 158) | def test_kendra_fallback(self, designer_login, dom_operator: DomOperat...
method test_kendra_redirect (line 184) | def test_kendra_redirect(self, designer_login, loaded_questions: list[...
method test_kendra_llm_retrieval (line 206) | def test_kendra_llm_retrieval(self, designer_login, loaded_questions: ...
FILE: .nightswatch/functional/test_knowledge_base.py
class TestKnowledgeBase (line 26) | class TestKnowledgeBase:
method test_setup (line 28) | def test_setup(self, designer_login, dom_operator: DomOperator):
method test_knowledge_base_with_bedrock_guardail (line 39) | def test_knowledge_base_with_bedrock_guardail(self, designer_login, do...
method test_knowledge_base_returns_custom_no_hits_message (line 58) | def test_knowledge_base_returns_custom_no_hits_message(self, designer_...
method test_knowledge_base_fallback (line 72) | def test_knowledge_base_fallback(self, designer_login, dom_operator: D...
method test_knowledge_base_with_advanced_config (line 94) | def test_knowledge_base_with_advanced_config(self, designer_login, dom...
method test_knowledge_base_with_multiple_fallback (line 117) | def test_knowledge_base_with_multiple_fallback(self, designer_login, d...
FILE: .nightswatch/functional/test_lambda_hooks.py
class TestLambdaHooks (line 12) | class TestLambdaHooks:
method test_setup (line 14) | def test_setup(self, designer_login, dom_operator: DomOperator):
method test_pre_processing_lambda_hooks (line 25) | def test_pre_processing_lambda_hooks(self, designer_login, dom_operato...
method test_post_processing_lambda_hooks (line 47) | def test_post_processing_lambda_hooks(self, designer_login, dom_operat...
method test_cleanup (line 66) | def test_cleanup(self, designer_login, dom_operator: DomOperator, ):
FILE: .nightswatch/functional/test_llm.py
class TestLlm (line 27) | class TestLlm:
method loaded_questions (line 30) | def loaded_questions(self) -> list[dict]:
method __create_question (line 36) | def __create_question(self, question: dict, edit_page):
method __get_question_by_qid (line 42) | def __get_question_by_qid(self, qid, loaded_questions: list[dict]) -> ...
method test_setup (line 45) | def test_setup(self, designer_login, dom_operator: DomOperator, loaded...
method test_llm_model_with_guardrail (line 69) | def test_llm_model_with_guardrail(self, designer_login, dom_operator: ...
method test_disambiguation (line 88) | def test_disambiguation(self, client_login, dom_operator: DomOperator,...
method test_ignore_utterances (line 104) | def test_ignore_utterances(self, designer_login, dom_operator: DomOper...
method test_inference (line 125) | def test_inference(self, designer_login, dom_operator: DomOperator, cw...
method test_llm_returns_custom_no_hits_message (line 145) | def test_llm_returns_custom_no_hits_message(self, designer_login, dom_...
method test_translation (line 158) | def test_translation(self, client_login, dom_operator: DomOperator, cw...
FILE: .nightswatch/functional/test_question_designer.py
class TestQuestionDesigner (line 18) | class TestQuestionDesigner:
method loaded_questions (line 21) | def loaded_questions(self) -> list[dict]:
method __create_question (line 27) | def __create_question(self, question: dict, edit_page):
method __get_question_by_qid (line 33) | def __get_question_by_qid(self, qid, loaded_questions: list[dict]) -> ...
method test_setup (line 36) | def test_setup(self, designer_login, dom_operator: DomOperator):
method test_create_question (line 50) | def test_create_question(self, designer_login, loaded_questions: list[...
method test_update_question (line 69) | def test_update_question(self, designer_login, loaded_questions: list[...
method test_delete_question (line 91) | def test_delete_question(self, designer_login, loaded_questions: list[...
method test_multiple_utterances (line 110) | def test_multiple_utterances(self, designer_login, loaded_questions: l...
method test_create_quiz_question (line 133) | def test_create_quiz_question(self, designer_login, loaded_questions: ...
method test_lex_rebuild (line 156) | def test_lex_rebuild(self, designer_login, dom_operator: DomOperator):
method test_create_slot_question (line 167) | def test_create_slot_question(self, designer_login, loaded_questions: ...
method test_slots_created_in_lex (line 207) | def test_slots_created_in_lex(self, designer_login, region: str, dom_o...
method test_slots_are_translated (line 229) | def test_slots_are_translated(self, designer_login, dom_operator: DomO...
method test_slots_are_deleted (line 265) | def test_slots_are_deleted(self, designer_login, region: str, dom_oper...
method test_create_response_card (line 293) | def test_create_response_card(self, designer_login, loaded_questions: ...
method test_question_topic (line 315) | def test_question_topic(self, designer_login, loaded_questions: list[d...
method extract_integer_from_string (line 342) | def extract_integer_from_string(self, string: str) -> int:
method test_response_handlebars (line 359) | def test_response_handlebars(self, designer_login, loaded_questions: l...
method test_response_handlebars_getQuestion (line 389) | def test_response_handlebars_getQuestion(self, designer_login, loaded_...
method test_filter (line 410) | def test_filter(self, designer_login, loaded_questions: list[dict], do...
method test_elicit_response (line 445) | def test_elicit_response(self, designer_login, loaded_questions: list[...
method test_question_branching (line 480) | def test_question_branching(self, designer_login, loaded_questions: li...
method test_rich_text (line 516) | def test_rich_text(self, designer_login, loaded_questions: list[dict],...
method test_lambda_hooks (line 569) | def test_lambda_hooks(self, designer_login, dom_operator: DomOperator,...
FILE: .nightswatch/functional/test_routing.py
class TestRouting (line 38) | class TestRouting:
method loaded_questions (line 41) | def loaded_questions(self) -> list[dict]:
method __create_question (line 47) | def __create_question(self, question: dict, edit_page):
method __get_question_by_qid (line 53) | def __get_question_by_qid(self, qid, loaded_questions: list[dict]) -> ...
method test_create_test_bot (line 56) | def test_create_test_bot(self, lex_client: LexClient, iam_client: IamC...
method test_setup (line 66) | def test_setup(self, designer_login, loaded_questions: list[dict], dom...
method test_bot_routing (line 99) | def test_bot_routing(self, client_login, loaded_questions: list[dict],...
method test_bot_routing_exit_utterance (line 115) | def test_bot_routing_exit_utterance(self, client_login, loaded_questio...
method test_pass_attribute_to_specialty_bot (line 131) | def test_pass_attribute_to_specialty_bot(self, client_login, loaded_qu...
method test_attribute_received_from_specialty_bot_and_chaining (line 147) | def test_attribute_received_from_specialty_bot_and_chaining(self, clie...
method test_bot_cleanup (line 163) | def test_bot_cleanup(self, lex_client: LexClient, iam_client: IamClient):
FILE: .nightswatch/functional/test_session_attribute.py
class TestSessionAttribute (line 18) | class TestSessionAttribute():
method loaded_questions (line 22) | def loaded_questions(self) -> list[dict]:
method __create_question (line 28) | def __create_question(self, question: dict, edit_page):
method __get_question_by_qid (line 34) | def __get_question_by_qid(self, qid, loaded_questions: list[dict]) -> ...
method test_setup (line 37) | def test_setup(self, designer_login, loaded_questions: list[dict], dom...
method test_default_returned_when_attribute_not_set (line 61) | def test_default_returned_when_attribute_not_set(self, client_login, l...
method test_set_session_attributes_using_ui (line 75) | def test_set_session_attributes_using_ui(self, client_login, loaded_qu...
method test_set_session_attributes_using_handlebars (line 91) | def test_set_session_attributes_using_handlebars(self, client_login, l...
FILE: .nightswatch/functional/test_settings.py
class TestSettings (line 14) | class TestSettings:
method loaded_questions (line 17) | def loaded_questions(self) -> list[dict]:
method __create_question (line 23) | def __create_question(self, question: dict, edit_page):
method __get_question_by_qid (line 29) | def __get_question_by_qid(self, qid, loaded_questions: list[dict]) -> ...
method test_custom_response (line 32) | def test_custom_response(self, designer_login, loaded_questions: list[...
method test_create_setting (line 62) | def test_create_setting(self):
method test_import_settings (line 69) | def test_import_settings(self):
method test_export_settings (line 76) | def test_export_settings(self):
method test_reset_settings (line 83) | def test_reset_settings(self):
method test_match_settings (line 90) | def test_match_settings(self):
method test_pii_rejection (line 99) | def test_pii_rejection(self):
method test_redaction (line 108) | def test_redaction(self):
FILE: .nightswatch/functional/test_translate.py
class TestTranslate (line 20) | class TestTranslate:
method loaded_questions (line 23) | def loaded_questions(self) -> list[dict]:
method __create_question (line 29) | def __create_question(self, question: dict, edit_page):
method __get_question_by_qid (line 35) | def __get_question_by_qid(self, qid, loaded_questions: list[dict]) -> ...
method test_setup (line 38) | def test_setup(self, designer_login, dom_operator: DomOperator, transl...
method test_client_conversation_english (line 56) | def test_client_conversation_english(self, client_login, dom_operator:...
method test_client_conversation_multi (line 72) | def test_client_conversation_multi(self, client_login, dom_operator: D...
method test_custom_terminology (line 88) | def test_custom_terminology(self, designer_login, loaded_questions: li...
method test_custom_terminology_translates_to_specified_term (line 117) | def test_custom_terminology_translates_to_specified_term(self, designe...
method test_lang_handlebar (line 143) | def test_lang_handlebar(self, designer_login, loaded_questions: list[d...
method test_lang_support (line 168) | def test_lang_support(self, designer_login, loaded_questions: list[dic...
FILE: .nightswatch/functional/test_tuning.py
class TestTuning (line 18) | class TestTuning:
method test_test_all (line 21) | def test_test_all(self, designer_login, dom_operator: DomOperator, s3_...
method test_test_single (line 36) | def test_test_single(self, designer_login, dom_operator: DomOperator):
FILE: source/bin/build.js
function create (line 39) | async function create(options) {
function log (line 60) | function log(message, show) {
FILE: source/bin/check.js
function run (line 46) | async function run(stack, options = {}) {
function bootstrap (line 80) | async function bootstrap() {
FILE: source/bin/check_bucket_ownership.js
function getAccountId (line 11) | async function getAccountId() {
function checkBucketOwner (line 27) | async function checkBucketOwner(bucket) {
function main (line 65) | async function main() {
FILE: source/bin/exports.js
function next (line 35) | async function next() {
FILE: source/bin/json.js
constant VERSION (line 11) | const VERSION = '9.0.6';
constant OM_JSONY (line 34) | const OM_JSONY = 1;
constant OM_JSON (line 35) | const OM_JSON = 2;
constant OM_INSPECT (line 36) | const OM_INSPECT = 3;
constant OM_COMPACT (line 37) | const OM_COMPACT = 4;
constant OM_FROM_NAME (line 38) | const OM_FROM_NAME = {
function getVersion (line 47) | function getVersion() {
function objCopy (line 56) | function objCopy(obj) {
function format (line 77) | function format(f) {
function _parseString (line 118) | function _parseString(s) {
function printHelp (line 139) | function printHelp() {
function parseArgv (line 281) | function parseArgv(argv) {
function chunkEmitter (line 493) | function chunkEmitter(opts) {
function getInput (line 706) | function getInput(opts, callback) {
function isInteger (line 754) | function isInteger(s) {
function parseLookup (line 767) | function parseLookup(lookup, lookupDelim) {
function parseInput (line 903) | function parseInput(buffer, obj, group, merge) {
function lookupDatum (line 1029) | function lookupDatum(datum, lookup) {
function printDatasets (line 1058) | function printDatasets(datasets, filename, headers, opts) {
function stringifyDatum (line 1106) | function stringifyDatum(datum, opts, isTTY) {
function printDatum (line 1157) | function printDatum(datum, opts, sep, alwaysPrintSep) {
function emit (line 1168) | function emit(s) {
function drainStdoutAndExit (line 1202) | function drainStdoutAndExit(code) {
function funcWithReturnFromSnippet (line 1225) | function funcWithReturnFromSnippet(js) {
function main (line 1238) | function main(argv) {
FILE: source/bin/launch.js
function syntax (line 96) | async function syntax(stack, options) {
function up (line 106) | async function up(stack, options) {
function update (line 162) | async function update(stack, options) {
function down (line 215) | async function down(stack, options) {
function sure (line 246) | async function sure(stack, options = {}) {
function log (line 263) | function log(message, options) {
function bootstrap (line 269) | async function bootstrap() {
FILE: source/bin/license.js
function js (line 39) | function js(name) {
function vue (line 49) | function vue(name) {
function insert (line 59) | function insert(file, license, position) {
FILE: source/bin/name.js
function run (line 36) | function run(stack, options = {}) {
FILE: source/bin/wait.js
function wait (line 21) | async function wait(stackname, options) {
function Spinner (line 61) | function Spinner(show) {
FILE: source/cli/aws_solutions/core/config.py
class SolutionConfigEnv (line 23) | class SolutionConfigEnv:
method __init__ (line 24) | def __init__(self, env_var, default: str = "", regex: re.Pattern = None):
method _get_value_or_default (line 29) | def _get_value_or_default(self) -> str:
method __get__ (line 34) | def __get__(self, instance, owner) -> str:
method __set__ (line 43) | def __set__(self, instance, value) -> None:
class Config (line 47) | class Config:
method botocore_config (line 55) | def botocore_config(self) -> botocore.config.Config:
method botocore_config (line 61) | def botocore_config(self, other_config: botocore.config.Config):
method _botocore_config_defaults (line 65) | def _botocore_config_defaults(self) -> Dict:
FILE: source/cli/aws_solutions/core/helpers.py
class EnvironmentVariableError (line 17) | class EnvironmentVariableError(Exception):
function get_aws_region (line 21) | def get_aws_region():
function get_aws_partition (line 33) | def get_aws_partition():
function get_session (line 56) | def get_session():
function get_service_client (line 63) | def get_service_client(service_name):
function get_service_resource (line 74) | def get_service_resource(service_name):
function get_aws_account (line 85) | def get_aws_account() -> str:
FILE: source/cli/aws_solutions/core/logging.py
function get_level (line 12) | def get_level():
function get_logger (line 26) | def get_logger(name):
FILE: source/cli/aws_solutions/qnabot/cli/qnabot_cli.py
function cli (line 16) | def cli(ctx) -> None:
function qna_import (line 56) | def qna_import(
function qna_export (line 121) | def qna_export(
FILE: source/cli/aws_solutions/qnabot/cli/qnabot_cli_helper.py
class BucketType (line 22) | class BucketType(Enum):
function get_bucket_name (line 28) | def get_bucket_name(cloudformation_stack_name: str, bucket_type: BucketT...
function initiate_import (line 49) | def initiate_import(
function initiate_export (line 121) | def initiate_export(cloudformation_stack_name: str, export_filename: str...
function download_export (line 207) | def download_export(bucket: str, export_filename: str, exportdatetime: d...
function get_import_status (line 268) | def get_import_status(bucket: str, source_filename: str, importdatetime:...
function get_export_status (line 319) | def get_export_status(bucket: str, export_filename: str, exportdatetime:...
function convert_json_to_jsonl (line 360) | def convert_json_to_jsonl(source_filename: str):
function convert_xlsx_to_jsonl (line 411) | def convert_xlsx_to_jsonl(source_filename: str):
function process_excel_data_frame (line 448) | def process_excel_data_frame(df):
function map_excel_headers_to_question_fields (line 487) | def map_excel_headers_to_question_fields(question):
function process_card_properties (line 501) | def process_card_properties(question):
function extract_questions (line 512) | def extract_questions(question):
function handle_dot_properties (line 526) | def handle_dot_properties(question, props_to_process):
function handle_dot_property (line 530) | def handle_dot_property(question, prop):
function convert_jsonl_to_json (line 556) | def convert_jsonl_to_json(str_file_contents: str):
function error_response (line 577) | def error_response(error_code: str, message: str, comments: str, status:...
FILE: source/cli/tests/aws_solutions/core/test_helpers.py
function valid_solution_env (line 21) | def valid_solution_env():
function test_get_aws_region_valid (line 31) | def test_get_aws_region_valid():
function test_get_service_client (line 35) | def test_get_service_client():
function test_get_service_resource (line 40) | def test_get_service_resource():
function test_get_aws_partition (line 55) | def test_get_aws_partition(region, partition, mocker):
function test_get_aws_account_id (line 61) | def test_get_aws_account_id(mocker):
FILE: source/cli/tests/aws_solutions/core/test_logging.py
function reset_logging_defaults (line 15) | def reset_logging_defaults():
function test_valid_levels (line 24) | def test_valid_levels(level):
function test_invalid_level (line 29) | def test_invalid_level():
function test_get_logger (line 35) | def test_get_logger():
function test_logger_log (line 40) | def test_logger_log(caplog):
FILE: source/cli/tests/aws_solutions/core/test_solution_config.py
function reset_botocore_config (line 15) | def reset_botocore_config():
function solution_id_valid (line 27) | def solution_id_valid(request):
function solution_id_invalid (line 35) | def solution_id_invalid(request):
function solution_version_valid (line 63) | def solution_version_valid(request):
function solution_version_invalid (line 71) | def solution_version_invalid(request):
function test_valid_solution_id (line 78) | def test_valid_solution_id(solution_id_valid):
function test_invalid_solution_id (line 83) | def test_invalid_solution_id(solution_id_invalid):
function test_valid_solution_version (line 88) | def test_valid_solution_version(solution_version_valid):
function test_invalid_solution_id (line 93) | def test_invalid_solution_id(solution_version_invalid):
function test_valid_botocore_config (line 98) | def test_valid_botocore_config(solution_id_valid, solution_version_valid):
function test_solution_config_env_reuse (line 103) | def test_solution_config_env_reuse():
function test_botocore_config_change (line 112) | def test_botocore_config_change():
function test_botocore_config_change_defaults (line 119) | def test_botocore_config_change_defaults():
FILE: source/cli/tests/aws_solutions/qnabot/fixtures/cloudformation_fixtures.py
function get_body (line 17) | def get_body():
function mock_create_stack (line 24) | def mock_create_stack(client_cloudformation=None, stack_name=None, param...
function cloudformation_stacks (line 31) | def cloudformation_stacks():
function cloudformation_stacks_fixture (line 42) | def cloudformation_stacks_fixture():
FILE: source/cli/tests/aws_solutions/qnabot/fixtures/s3_fixtures.py
function mock_import_event (line 16) | def mock_import_event(*args):
function mock_export_event (line 55) | def mock_export_event(*args):
FILE: source/cli/tests/aws_solutions/qnabot/test_qnabot_cli.py
function test_cli (line 13) | def test_cli():
FILE: source/cli/tests/aws_solutions/qnabot/test_qnabot_cli_helper.py
function test_qna_import_json (line 28) | def test_qna_import_json( # NOSONAR
function test_qna_import_xlsx (line 56) | def test_qna_import_xlsx(cloudformation_stacks_fixture, caplog):
function test_qna_import_xlsx_file_not_found (line 113) | def test_qna_import_xlsx_file_not_found(cloudformation_stacks_fixture, c...
function test_qna_import_xlsx_exception (line 133) | def test_qna_import_xlsx_exception(cloudformation_stacks_fixture, capfd):
function test_qna_export_json (line 151) | def test_qna_export_json( # NOSONAR
function test_qna_import_invalid_stack (line 182) | def test_qna_import_invalid_stack( # NOSONAR
FILE: source/cli/tests/conftest.py
function aws_environment_variables (line 14) | def aws_environment_variables():
FILE: source/lambda/cfn/index.js
function dispatch (line 50) | function dispatch(event, context) {
FILE: source/lambda/cfn/lib/ApiDeployment.js
method Create (line 14) | Create(params, reply) {
method Update (line 35) | Update(ID, params, oldparams, reply) {
method Delete (line 60) | Delete(ID, params, reply) {
function run (line 69) | function run(fnc) {
FILE: source/lambda/cfn/lib/CognitoDomain.js
method constructor (line 13) | constructor() {
method Create (line 17) | async Create(params, reply) {
method Update (line 30) | async Update(ID, params, oldparams, reply) {
method Delete (line 34) | async Delete(ID, params, reply) {
function generate (line 47) | function generate(n) {
FILE: source/lambda/cfn/lib/CognitoLogin.js
method constructor (line 14) | constructor() {
method Create (line 18) | async Create(params, reply) {
method Update (line 64) | async Update(ID, params, oldparams, reply) {
FILE: source/lambda/cfn/lib/CognitoRole.js
method constructor (line 13) | constructor() {
method Create (line 17) | async Create(params, reply) {
method Update (line 41) | async Update(ID, params, oldparams, reply) {
method Delete (line 45) | async Delete(ID, params, reply) {
FILE: source/lambda/cfn/lib/CognitoUrl.js
method constructor (line 7) | constructor() {
method Update (line 11) | Update(ID, params, oldparams, reply) {
method Create (line 15) | Create(params, reply) {
FILE: source/lambda/cfn/lib/ESCognitoClient.js
method constructor (line 13) | constructor() {
method Create (line 17) | async Create(params, reply) {
method Update (line 21) | async Update(Id, params, oldparams, reply) {
function run (line 26) | async function run(params, reply) {
FILE: source/lambda/cfn/lib/LambdaVersion.js
method constructor (line 13) | constructor() {
method Create (line 17) | async Create(params, reply) {
method Update (line 29) | async Update(ID, params, oldparams, reply) {
FILE: source/lambda/cfn/lib/ModelAccess.js
method Create (line 33) | async Create(params, reply) {
method Update (line 60) | Update(ID, params, oldparams, reply) {
method Delete (line 64) | Delete(ID, params, reply) {
method getModelArns (line 75) | async getModelArns(modelId, requiredOutputModality = 'TEXT') {
method getFoundationModelArn (line 99) | async getFoundationModelArn(modelId, requiredOutputModality, requiredInf...
method getInferenceProfileArns (line 149) | async getInferenceProfileArns(inferenceProfileId, requiredOutputModality) {
method isInferenceProfile (line 190) | isInferenceProfile(modelId) {
FILE: source/lambda/cfn/lib/OpenSearchUpdates.js
method constructor (line 13) | constructor() {
method Create (line 16) | async Create(params, reply){
method Update (line 34) | async Update(ID, params, oldparams, reply) {
FILE: source/lambda/cfn/lib/PostUpgradeImport.js
function copyData (line 12) | async function copyData(oldS3ExportParams, s3exportparms, s3importparms) {
function waitForImport (line 47) | async function waitForImport(s3params, timeout) {
function run_import (line 72) | async function run_import(params) {
method AsyncCreate (line 120) | async AsyncCreate() {
method AsyncUpdate (line 124) | async AsyncUpdate(ID, params, oldparams) {
method AsyncDelete (line 128) | async AsyncDelete() {
FILE: source/lambda/cfn/lib/PreUpgradeExport.js
function waitForExport (line 12) | async function waitForExport(oldS3Params, s3params, timeout) {
function run_export (line 50) | async function run_export(params) {
method AsyncCreate (line 93) | async AsyncCreate() {
method AsyncUpdate (line 97) | async AsyncUpdate(ID, params, oldparams) {
method AsyncDelete (line 101) | async AsyncDelete() {
FILE: source/lambda/cfn/lib/S3Lambda.js
method constructor (line 16) | constructor() {
method Create (line 20) | Create(params, reply) {
method Delete (line 36) | Delete(ID, params, reply) {
method Update (line 40) | Update(ID, params, oldparams, reply) {
FILE: source/lambda/cfn/lib/S3Unzip.js
method constructor (line 17) | constructor() {
method Create (line 20) | async Create(params, reply) {
method Update (line 45) | async Update(ID, params, oldparams, reply) {
method Delete (line 49) | Delete(ID, params, reply) {
function getFiles (line 54) | async function getFiles(params) {
FILE: source/lambda/cfn/lib/S3Version.js
method constructor (line 17) | constructor() {
method Create (line 20) | async Create(params, reply){
method Update (line 34) | async Update(ID, params, oldparams, reply) {
FILE: source/lambda/cfn/lib/SettingsInitializer.js
function getDynamoDBClient (line 18) | function getDynamoDBClient() {
function getSSMClient (line 25) | function getSSMClient() {
function updateDefaultSettingsFromParams (line 32) | async function updateDefaultSettingsFromParams(params, tableName) {
function updatePrivateSettings (line 72) | async function updatePrivateSettings(params, tableName, writePrivateSett...
function writeSettingsToDynamoDB (line 123) | async function writeSettingsToDynamoDB(tableName, settings) {
function addNewSettings (line 166) | async function addNewSettings(tableName, defaultSettings) {
function migrateFromSSM (line 212) | async function migrateFromSSM(tableName, ssmParameters) {
method Create (line 277) | async Create(params, reply) {
method Update (line 307) | async Update(ID, params, old_params, reply) {
method Delete (line 328) | async Delete(ID, params, reply) {
FILE: source/lambda/cfn/lib/Variable.js
method constructor (line 10) | constructor() {
method Create (line 14) | Create(params, reply) {
method Update (line 26) | Update(ID, params, oldparams, reply) {
function id (line 31) | function id(params) {
FILE: source/lambda/cfn/lib/base.js
method Create (line 7) | Create(params, reply) {
method Update (line 11) | Update(ID, params, oldparams, reply) {
method Delete (line 15) | Delete(ID, params, reply) {
FILE: source/lambda/cfn/lib/lex.js
function makeid (line 14) | function makeid(prefix) {
function id (line 22) | function id(length) {
function clean (line 30) | function clean(name) {
function run (line 49) | function run(fnc, params) {
class Lex (line 83) | class Lex {
method constructor (line 84) | constructor(type) {
method checksum (line 92) | checksum(id, version) {
method checksumIntentOrSlotType (line 100) | checksumIntentOrSlotType(id, version) {
method checksumBotAlias (line 108) | checksumBotAlias(botName, name) {
method slotTypeVersions (line 123) | slotTypeVersions(id) {
method intentVersions (line 137) | intentVersions(id) {
method mapForIntentVersions (line 150) | mapForIntentVersions(intents) {
method botVersions (line 178) | botVersions(id) {
method latestBotVersion (line 191) | latestBotVersion(botName) {
method mapForSlotTypeVersions (line 209) | mapForSlotTypeVersions(slots) {
method name (line 234) | name(params) {
method Create (line 251) | Create(params, reply) {
method createGeneric (line 279) | createGeneric(params, start, self, reply) {
method createBot (line 290) | createBot(params, start, self, reply) {
method createIntent (line 334) | createIntent(params, start, self, reply) {
method createBotAlias (line 365) | createBotAlias(params, start, self, reply) {
method Update (line 391) | Update(ID, params, oldparams, reply) {
method updateGeneric (line 440) | updateGeneric(params, self, reply, ID) {
method updateBotAlias (line 456) | updateBotAlias(params, ID, self, reply) {
method updateSlotType (line 475) | updateSlotType(params, ID, self, reply) {
method updateIntent (line 494) | updateIntent(params, ID, self, reply) {
method updateBot (line 536) | updateBot(params, ID, self, reply) {
method Delete (line 568) | Delete(ID, params, reply) {
FILE: source/lambda/cfn/lib/util/promise.js
class NativePromise (line 6) | class NativePromise extends Promise {
FILE: source/lambda/cfn/test/lib/SettingsInitializer.test.js
function initializePrivateSettings (line 15) | function initializePrivateSettings(parameterSubset) {
FILE: source/lambda/common-modules-layer/opensearch-client/connection.js
function getCredentials (line 12) | function getCredentials() {
FILE: source/lambda/connect/index.js
function createCallFlowLexV2 (line 23) | async function createCallFlowLexV2() {
FILE: source/lambda/es-proxy-layer/lib/bedrock/AmazonEmbeddings.js
class AmazonEmbeddings (line 8) | class AmazonEmbeddings extends BedrockModelProviderPrototype {
method constructor (line 9) | constructor() {
method setPrompt (line 14) | setPrompt(prompt) {
method getResponseBody (line 18) | getResponseBody(response) {
FILE: source/lambda/es-proxy-layer/lib/bedrock/AmazonNovaEmbeddings.js
class AmazonNovaEmbeddings (line 8) | class AmazonNovaEmbeddings extends BedrockModelProviderPrototype {
method constructor (line 9) | constructor() {
method setPrompt (line 23) | setPrompt(prompt) {
method getResponseBody (line 27) | getResponseBody(response) {
FILE: source/lambda/es-proxy-layer/lib/bedrock/BedrockModelProviderPrototype.js
class BedrockModelProviderPrototype (line 8) | class BedrockModelProviderPrototype {
method constructor (line 9) | constructor() {
method getParameters (line 13) | getParameters() {
method setParameters (line 17) | setParameters(params) {
method setPrompt (line 21) | setPrompt(prompt) {
method parseResponseBody (line 25) | parseResponseBody(response) {
FILE: source/lambda/es-proxy-layer/lib/bedrock/CohereEmbeddings.js
class CohereEmbeddings (line 8) | class CohereEmbeddings extends BedrockModelProviderPrototype {
method constructor (line 9) | constructor() {
method setPrompt (line 17) | setPrompt(prompt) {
method getResponseBody (line 21) | getResponseBody(response) {
FILE: source/lambda/es-proxy-layer/lib/bedrock/applyGuardrail.js
function applyGuardrail (line 11) | async function applyGuardrail(guardrailIdentifier, guardrailVersion, sou...
FILE: source/lambda/es-proxy-layer/lib/bedrock/bedrockAgents.js
function isNoHitsResponse (line 22) | function isNoHitsResponse(req, response) {
function generateResponse (line 28) | async function generateResponse(input, streamingAttributes, res) {
function generateSourceLinks (line 47) | async function generateSourceLinks(urls, KNOWLEDGE_BASE_S3_SIGNED_URL_EX...
function retrieveAndGenerateStream (line 64) | async function retrieveAndGenerateStream(input, streamingAttributes) {
function createHit (line 112) | async function createHit(req, response) {
function processCitations (line 157) | function processCitations(response) {
function createModelArn (line 190) | function createModelArn(modelId) {
function processRequest (line 203) | function processRequest(req) {
function bedrockRetrieveAndGenerate (line 282) | async function bedrockRetrieveAndGenerate(req, res) {
FILE: source/lambda/es-proxy-layer/lib/bedrock/bedrockClient.js
function getBedrockClient (line 23) | function getBedrockClient(configCode) {
function isEmbedding (line 59) | function isEmbedding(modelId) {
function guardrailResponse (line 63) | function guardrailResponse(stopReason) {
function bedrockClient (line 69) | async function bedrockClient(modelId, input, streamingAttributes) {
function converseStream (line 125) | async function converseStream(modelId, client, input, streamingAttribute...
FILE: source/lambda/es-proxy-layer/lib/bedrock/bedrockLLMProvider.js
class BedrockLlm (line 10) | class BedrockLlm extends BedrockModelProviderPrototype {
method constructor (line 11) | constructor() {
method setPrompt (line 22) | setPrompt(prompt) {
method setSystemPrompt (line 36) | setSystemPrompt(system) {
method setParameters (line 44) | setParameters(params) {
method setGuardrails (line 61) | setGuardrails(guardrails, query, groundingSource) {
FILE: source/lambda/es-proxy-layer/lib/bedrock/bedrockModelConstants.js
constant FOUNDATION_MODEL_MAPPING (line 10) | const FOUNDATION_MODEL_MAPPING = {
function applyModelIdMapping (line 36) | function applyModelIdMapping(modelId) {
FILE: source/lambda/es-proxy-layer/lib/bedrock/bedrockModels.js
function isEmbedding (line 13) | function isEmbedding(modelId) {
function getProviderClass (line 17) | function getProviderClass(modelId) {
function invokeBedrockModel (line 33) | async function invokeBedrockModel(modelId, prompt, options = {}) {
FILE: source/lambda/es-proxy-layer/lib/cfn.js
function run_es_query (line 11) | async function run_es_query(event) {
function remove_alias_from_indices (line 37) | async function remove_alias_from_indices(api, index_alias, res, index_na...
FILE: source/lambda/es-proxy-layer/lib/cleanmetrics.js
function sendDelete (line 22) | async function sendDelete(indexName, timeBack) {
FILE: source/lambda/es-proxy-layer/lib/dialog-event/processDialogEvent.js
function processDialogEvent (line 11) | async function processDialogEvent(req, res) {
FILE: source/lambda/es-proxy-layer/lib/dialog-event/processSlots.js
function useCachedValue (line 9) | function useCachedValue(slotName, slot_sessionAttrName, res, slotRequire...
function useSlotValue (line 27) | function useSlotValue(slotName, slotValue, res, slotValueCached, slot_se...
function processSlots (line 40) | function processSlots(req, res, hit) {
FILE: source/lambda/es-proxy-layer/lib/embeddings.js
function getEmbeddingsLambda (line 14) | async function getEmbeddingsLambda(type_q_or_a, input, settings) {
function getEmbeddingsBedrock (line 27) | async function getEmbeddingsBedrock(type_q_or_a, input, settings) {
FILE: source/lambda/es-proxy-layer/lib/es-logging.js
function stringifySessionAttribues (line 16) | function stringifySessionAttribues(res) {
FILE: source/lambda/es-proxy-layer/lib/es_query.js
function isESonly (line 13) | async function isESonly(req, query_params) {
function score_threshold_check (line 51) | function score_threshold_check(resp, threshold) {
function run_query_es (line 60) | async function run_query_es(req, query_params) {
function getMatchedField (line 143) | function getMatchedField(isQID, gothits) {
function getThreshold (line 153) | function getThreshold(isQID, query_params) {
function run_qid_query_es (line 166) | async function run_qid_query_es(params, qid) {
function hasJsonStructure (line 183) | function hasJsonStructure(str) {
function isQuestionAllStopwords (line 195) | function isQuestionAllStopwords(question) {
FILE: source/lambda/es-proxy-layer/lib/esbodybuilder.js
function build_qid_query (line 14) | function build_qid_query(params) {
function build_query (line 26) | function build_query(params) {
function queryFilter (line 205) | function queryFilter(keywords, params, query, filter_query_a, filter_que...
FILE: source/lambda/es-proxy-layer/lib/fulfillment-event/evaluateConditionalChaining.js
function handleErrors (line 15) | function handleErrors(message, errors) {
function evaluateNextQuestion (line 35) | async function evaluateNextQuestion(conditionalChaining, req, res, error...
function evaluateConditionalChaining (line 91) | async function evaluateConditionalChaining(req, res, hit, conditionalCha...
FILE: source/lambda/es-proxy-layer/lib/fulfillment-event/getHit.js
function runQuery (line 22) | async function runQuery(req, query_params, kendraIndex) {
function getSourceLinksFromPassages (line 34) | function getSourceLinksFromPassages(inputText) {
function kendraFallback (line 47) | async function kendraFallback(req, res) {
function encryptConditionalChainingIfSet (line 77) | function encryptConditionalChainingIfSet(hit) {
function getNoHitsResponse (line 87) | async function getNoHitsResponse(query_params, res, req, errors, KENDRA_...
function setSessionTopic (line 104) | function setSessionTopic(hit, res) {
function invokeLambdaHook (line 124) | async function invokeLambdaHook(hit, req, res) {
function copyPassageFieldToAnswerFields (line 162) | function copyPassageFieldToAnswerFields(hit) {
function runFirstQuery (line 177) | async function runFirstQuery(req, query_params, KENDRA_FAQ_INDEX, res) {
function opensearchFallback (line 189) | async function opensearchFallback(req, query_params) {
function kendraRedirect (line 199) | async function kendraRedirect(hit, req, res, ALT_SEARCH_KENDRA_FALLBACK_...
function getQuestion (line 237) | function getQuestion(req) {
function getHit (line 338) | async function getHit(req, res) {
FILE: source/lambda/es-proxy-layer/lib/fulfillment-event/invokeLambda.js
function getLambdaName (line 13) | function getLambdaName(lambdaRef) {
function invokeLambda (line 22) | async function invokeLambda(lambdaRef, req, res) {
FILE: source/lambda/es-proxy-layer/lib/fulfillment-event/mergeNext.js
function mergeMarkdown (line 9) | function mergeMarkdown(hit1, hit2) {
function mergeSSML (line 36) | function mergeSSML(hit1, hit2) {
function mergeNext (line 66) | function mergeNext(hit1, hit2) {
FILE: source/lambda/es-proxy-layer/lib/fulfillment-event/processFulfillmentEvent.js
function markConditionalChainingUsed (line 21) | async function markConditionalChainingUsed(req) {
function executeConditionalChaining (line 51) | async function executeConditionalChaining(hit, req, res) {
function updateChatHistory (line 77) | async function updateChatHistory(req, LLM_CHAT_HISTORY_MAX_MESSAGES, mes...
function shouldGenerateQuery (line 97) | function shouldGenerateQuery(req) {
function getInitialHit (line 116) | async function getInitialHit(res, req) {
function translateResponse (line 151) | async function translateResponse(hit, ENABLE_MULTI_LANGUAGE_SUPPORT, usr...
function prependDebugMsg (line 167) | function prependDebugMsg(req, usrLang, nativeLangCode, hit, errors) {
function processFulfillmentEvent (line 221) | async function processFulfillmentEvent(req, res) {
FILE: source/lambda/es-proxy-layer/lib/fulfillment-event/qid.js
function utteranceIsQid (line 6) | function utteranceIsQid(utterance) {
FILE: source/lambda/es-proxy-layer/lib/fulfillment-event/runKendraQuery.js
function runKendraQuery (line 11) | async function runKendraQuery(req, query_params) {
FILE: source/lambda/es-proxy-layer/lib/fulfillment-event/runLlmQa.js
function prependLlmQaAnswer (line 9) | function prependLlmQaAnswer(prefix, qa_answer, hit) {
function runLlmQa (line 25) | async function runLlmQa(req, hit) {
FILE: source/lambda/es-proxy-layer/lib/fulfillment-event/safeExpressionEvaluator.js
constant BLOCKED_PROPERTIES (line 28) | const BLOCKED_PROPERTIES = new Set([
constant BLOCKED_OPERATORS (line 39) | const BLOCKED_OPERATORS = new Set(['=', '++', '--']);
constant ALLOWED_METHODS (line 42) | const ALLOWED_METHODS = new Set([
function tokenize (line 69) | function tokenize(expression) {
function checkBlockedProperties (line 124) | function checkBlockedProperties(token) {
function checkBracketNotation (line 143) | function checkBracketNotation(token) {
function checkAssignmentOperator (line 163) | function checkAssignmentOperator(token) {
function checkMethodCall (line 186) | function checkMethodCall(token, prevToken, nextToken) {
function checkStandaloneFunctionCall (line 215) | function checkStandaloneFunctionCall(token, prevToken, nextToken) {
function isLiteralOrKeyword (line 231) | function isLiteralOrKeyword(token) {
function checkTopLevelIdentifier (line 255) | function checkTopLevelIdentifier(token, prevToken, contextKeys) {
function validateTokensCoverExpression (line 278) | function validateTokensCoverExpression(expression, tokens) {
function validateTokens (line 306) | function validateTokens(tokens, context) {
function evaluateExpression (line 344) | function evaluateExpression(expression, context) {
function safeEvaluate (line 383) | function safeEvaluate(expression, context) {
FILE: source/lambda/es-proxy-layer/lib/fulfillment-event/updateResWithHit.js
function updateSessionNavigation (line 9) | function updateSessionNavigation(res, req) {
function addSessionAttributes (line 45) | function addSessionAttributes(hit, res) {
function addTags (line 54) | function addTags(hit, res) {
function addAnswerSource (line 63) | function addAnswerSource(ansSource, res) {
function updateSsml (line 76) | function updateSsml(req, res) {
function addAltMessages (line 87) | function addAltMessages(res) {
function addCard (line 100) | function addCard(res) {
function addReprompt (line 117) | function addReprompt(res) {
function updateResWithHit (line 131) | function updateResWithHit(req, res, hit) {
FILE: source/lambda/es-proxy-layer/lib/fulfillment-event/utterance.js
function inIgnoreUtterances (line 6) | function inIgnoreUtterances(utterance, ignoreUtterancesSetting) {
FILE: source/lambda/es-proxy-layer/lib/getConnectionId.js
function getConnectionId (line 19) | async function getConnectionId(sessionId, tableName) {
FILE: source/lambda/es-proxy-layer/lib/handlebars.js
function convertOperatorToFunc (line 20) | function convertOperatorToFunc(operator) {
function replaceAsync (line 216) | async function replaceAsync(str, regex) {
function handleSignS3 (line 231) | async function handleSignS3(str) {
function handleSa (line 237) | function handleSa(hit_out, hit, context) {
function handleR (line 251) | async function handleR(r, hit_out, context) {
function handleButtons (line 291) | function handleButtons(r, hit_out, context) {
function handleRp (line 310) | function handleRp(rp, hit_out, context) {
function handleSsml (line 325) | async function handleSsml(ssml, hit_out, context) {
function handleMarkdown (line 341) | async function handleMarkdown(markdown, hit_out, context) {
function handleA (line 357) | async function handleA(a, hit_out, context) {
FILE: source/lambda/es-proxy-layer/lib/handler.js
function get_settings (line 18) | async function get_settings() {
function build_additem_embeddings (line 25) | async function build_additem_embeddings(event, settings) {
function get_es_query (line 55) | async function get_es_query(event, settings) {
function run_query_es (line 93) | async function run_query_es(event, settings) {
function run_query_kendra (line 114) | async function run_query_kendra(event, kendra_index, language) {
FILE: source/lambda/es-proxy-layer/lib/hits_topic_tiebreaker.js
function is_score_match (line 7) | function is_score_match(score, top_score) {
function is_topic_match (line 13) | function is_topic_match(topic1, topic2) {
function sort_hits_by_topic_match (line 30) | function sort_hits_by_topic_match(topic, hits) {
function hits_topic_tiebreaker (line 43) | function hits_topic_tiebreaker(topic, hits) {
FILE: source/lambda/es-proxy-layer/lib/kendra.js
function allow_kendra_result (line 24) | function allow_kendra_result(kendra_result, minimumScore, response_types) {
function confidence_filter (line 37) | function confidence_filter(minimumScore, kendra_result) {
function type_filter (line 49) | function type_filter(response_types, kendra_result) {
function create_hit (line 52) | function create_hit(answermessage, markdown, ssml, hit_count, debugResul...
function create_debug_object (line 72) | function create_debug_object(kendra_result) {
function addMarkdownHighlights (line 87) | function addMarkdownHighlights(textIn, hlBeginOffset, hlEndOffset, highl...
function isHighlightInLink (line 103) | function isHighlightInLink(textIn, hlBeginOffset) {
function mergeIntervals (line 122) | function mergeIntervals(intervals) {
function longestInterval (line 161) | function longestInterval(intervals) {
function isSyncedFromQnABot (line 174) | function isSyncedFromQnABot(kendra_result) {
function routeKendraRequest (line 193) | async function routeKendraRequest(event, context) {
function getAnswerMsg (line 266) | function getAnswerMsg(element, returnTopAnswer, seenTop, answerMessageMd...
function buildDocInfoAndSpeechMsg (line 297) | function buildDocInfoAndSpeechMsg(seenTop, element, allFilteredMessages,...
function shortenSpeechMsg (line 334) | function shortenSpeechMsg(seenTop, sorted_highlights, element, speechMes...
function getAnswerTextMd (line 345) | function getAnswerTextMd(element) {
function getMarkdownMessage (line 359) | async function getMarkdownMessage(answerMessageMd, answerMessage, event,...
function getSsmlMessage (line 410) | function getSsmlMessage(foundAnswerCount, foundDocumentCount, answerMess...
function getKendraIndexes (line 431) | function getKendraIndexes(event) {
function isDocType (line 446) | function isDocType(element) {
function isQaType (line 450) | function isQaType(element) {
function isAnswerType (line 454) | function isAnswerType(element, foundAnswerCount) {
function appendQueryAndIndexId (line 459) | function appendQueryAndIndexId(items, QueryId, originalKendraIndexId) {
function getResultItems (line 468) | function getResultItems(resArray, minimumScore, searchTypes) {
function generateAnswerFromKendra (line 476) | async function generateAnswerFromKendra(event, resArray, useOriginalLang...
FILE: source/lambda/es-proxy-layer/lib/kendraClient.js
function getKendraClient (line 16) | function getKendraClient(maxRetries, retryDelay) {
function queryKendra (line 37) | function queryKendra(resArray, kendraArgs, maxRetries, retryDelay, usrCo...
function retrievalKendra (line 70) | async function retrievalKendra(params, maxRetries, retryDelay) {
function determineKendraLanguage (line 77) | function determineKendraLanguage(req) {
function shouldUseOriginalLanguageQuery (line 102) | function shouldUseOriginalLanguageQuery(req, origQuestion, question) {
function getKendraIndexToken (line 129) | function getKendraIndexToken(req) {
FILE: source/lambda/es-proxy-layer/lib/kendraQuery.js
function allow_kendra_result (line 19) | function allow_kendra_result(kendra_result, minimum_score) {
function confidence_filter (line 28) | function confidence_filter(minimum_score, kendra_result) {
function asyncForEach (line 40) | async function asyncForEach(array, callback) {
function processKendraResults (line 46) | async function processKendraResults(resArray, request_params) {
function faqResultAllowed (line 90) | function faqResultAllowed(element, request_params, foundAnswerCount) {
function getHitFromOpensearch (line 94) | async function getHitFromOpensearch(element, request_params) {
function routeKendraRequest (line 114) | async function routeKendraRequest(request_params) {
FILE: source/lambda/es-proxy-layer/lib/kendraRetrieve.js
function createHit (line 12) | function createHit(docs, hitCount) {
function getIndexIDs (line 33) | function getIndexIDs(req) {
function getResult (line 42) | async function getResult(resp, index, signS3Urls, expireSeconds) {
function getQuery (line 55) | function getQuery(req) {
function kendraRetrieve (line 82) | async function kendraRetrieve(req) {
FILE: source/lambda/es-proxy-layer/lib/keywords.js
function get_keywords_from_comprehend (line 18) | async function get_keywords_from_comprehend(params) {
function detectSyntaxUsingComprehend (line 82) | async function detectSyntaxUsingComprehend(comprehend_params, keyword_sy...
function get_keywords (line 111) | async function get_keywords(params) {
FILE: source/lambda/es-proxy-layer/lib/llm.js
function make_qa_prompt (line 28) | async function make_qa_prompt(req, promptTemplateStr, context, input, qu...
function make_qenerate_query_prompt (line 53) | async function make_qenerate_query_prompt(req, promptTemplateStr) {
function invoke_lambda (line 79) | async function invoke_lambda(prompt, parameters, settings, options = {}) {
function invoke_bedrock (line 116) | async function invoke_bedrock(prompt, modelId, parameters, options = {}) {
function clean_standalone_query (line 123) | function clean_standalone_query(query) {
function chatMemorySerialise (line 165) | async function chatMemorySerialise(chatMessageHistory, max = 50, human_p...
function chatMemoryParse (line 181) | async function chatMemoryParse(json_messages, max = 50) {
function get_question (line 198) | function get_question(req) {
function get_query (line 202) | function get_query(req) {
function invokeLlm (line 207) | async function invokeLlm(llmType, prompt, modelId, parameters, settings,...
function isNoHits (line 318) | function isNoHits(req, answer) {
FILE: source/lambda/es-proxy-layer/lib/redactHelper.js
function processKeysForRedact (line 11) | function processKeysForRedact(obj, fullRedaction = false) {
FILE: source/lambda/es-proxy-layer/lib/request.js
function next (line 12) | function next(count, res, rej, request) {
FILE: source/lambda/es-proxy-layer/lib/sanitizeOutput.js
function sanitize (line 9) | function sanitize(data) {
function escapeHashMarkdown (line 19) | function escapeHashMarkdown(text) {
FILE: source/lambda/es-proxy-layer/lib/signS3URL.js
function signS3URL (line 12) | async function signS3URL(url, expireSecs) {
function signUrls (line 52) | async function signUrls(urlArr, expireSecs) {
function signUrl (line 57) | async function signUrl(url, expireSecs) {
FILE: source/lambda/es-proxy-layer/lib/supportedLanguages.js
method getSupportedLanguages (line 439) | getSupportedLanguages() {
method getLanguageErrorMessages (line 442) | getLanguageErrorMessages() {
method getComprehendSyntaxSupportedLanguages (line 445) | getComprehendSyntaxSupportedLanguages() {
method getKendraSupportedLanguages (line 448) | getKendraSupportedLanguages() {
FILE: source/lambda/es-proxy-layer/lib/translate.js
function get_terminologies (line 13) | async function get_terminologies(sourceLang) {
function get_translation (line 23) | async function get_translation(userText, targetLang, req) {
function translateField (line 66) | async function translateField(field, hit, usrLang, req) {
function translateButtons (line 79) | async function translateButtons(hit, usrLang, req) {
FILE: source/lambda/es-proxy-layer/lib/truncate.js
function countTokens (line 15) | function countTokens(message) {
function truncateByNumTokens (line 29) | async function truncateByNumTokens(message, chunkSize) {
function createTruncatedPrompt (line 52) | async function createTruncatedPrompt(promptTemplateStr, promptTemplate, ...
FILE: source/lambda/es-proxy-layer/test/bedrockAgents.test.js
method [Symbol.asyncIterator] (line 221) | *[Symbol.asyncIterator]() {
method [Symbol.asyncIterator] (line 374) | *[Symbol.asyncIterator]() {
FILE: source/lambda/es-proxy-layer/test/bedrockModels.test.js
method [Symbol.asyncIterator] (line 375) | [Symbol.asyncIterator]() {
method [Symbol.asyncIterator] (line 454) | [Symbol.asyncIterator]() {
method [Symbol.asyncIterator] (line 535) | [Symbol.asyncIterator]() {
FILE: source/lambda/es-proxy-layer/test/cfn.test.js
class TestError (line 14) | class TestError extends Error {
method constructor (line 15) | constructor() {
FILE: source/lambda/export/createFAQ.js
function s3Uploader (line 19) | async function s3Uploader(s3Client, params) {
function faqConverter (line 36) | async function faqConverter(kendraClient, params) {
function faqDeleter (line 66) | async function faqDeleter(kendraClient, params) {
function wait (line 86) | function wait(ms = 1000) {
function poll (line 93) | async function poll(fn, fnCondition, ms) {
function faqLister (line 120) | async function faqLister(kendraClient, params) {
function execFuncHandleThrottleException (line 131) | async function execFuncHandleThrottleException(func, client, params) {
function createFAQ (line 152) | async function createFAQ(params) {
FILE: source/lambda/export/index.js
function getStatusAndStartNextStep (line 37) | async function getStatusAndStartNextStep(Bucket, Key, VersionId, nextSte...
FILE: source/lambda/export/kendraSync.js
function get_settings (line 21) | async function get_settings() {
function update_status (line 107) | async function update_status(bucket, new_stat) {
FILE: source/lambda/export/lib/start.js
function query (line 23) | function query(filter) {
FILE: source/lambda/export/parseJSON.js
function qnaJsontoKendraJsonParser (line 17) | async function qnaJsontoKendraJsonParser(params) {
FILE: source/lambda/export/test/index.fixtures.js
function mockStream (line 10) | function mockStream(config, s3Mock, payload = "") {
FILE: source/lambda/export/test/index.test.js
function generateConfigAndVersionId (line 39) | function generateConfigAndVersionId(currentStatus) {
function initializeStartStepMocks (line 45) | function initializeStartStepMocks() {
function initializeInProgressStepMocks (line 66) | function initializeInProgressStepMocks(startVersionId) {
function initializeJoinStepMocks (line 87) | function initializeJoinStepMocks(inProgressVersionId) {
function initializeCleanStepMocks (line 108) | function initializeCleanStepMocks(lexVersionId) {
FILE: source/lambda/fulfillment/lib/middleware/1_parse.js
function get_settings (line 14) | async function get_settings() {
function getClientType (line 28) | function getClientType(req) {
function replaceSubstrings (line 65) | function replaceSubstrings(SEARCH_REPLACE_QUESTION_SUBSTRINGS, req) {
function parseRequestByType (line 86) | async function parseRequestByType(req) {
FILE: source/lambda/fulfillment/lib/middleware/2_preprocess.js
function get_userInfo (line 16) | async function get_userInfo(userId, idattrs, userPrefs = undefined) {
function update_userInfo (line 72) | async function update_userInfo(userId, req_userInfo, ttlDays) {
function runPreProcessLambda (line 88) | async function runPreProcessLambda(req, res) {
function runPreProcessGuardrail (line 109) | async function runPreProcessGuardrail(req, res) {
function decodeSessionToken (line 147) | async function decodeSessionToken(req) {
function replaceQuestionIfPiiDetected (line 186) | async function replaceQuestionIfPiiDetected(req) {
FILE: source/lambda/fulfillment/lib/middleware/3_query.js
function specialtyBotInvocation (line 43) | async function specialtyBotInvocation(req, res) {
function getPostQuery (line 143) | async function getPostQuery(queryLambdaArn, req, res, specialtyArn) {
function switchToNewBot (line 210) | function switchToNewBot(localEsQueryResults) {
function botIsFulfilled (line 216) | function botIsFulfilled(progress) {
function specialtyBotIsComplete (line 220) | function specialtyBotIsComplete(resp) {
FILE: source/lambda/fulfillment/lib/middleware/4_hook.js
function runPostProcessGuardrail (line 11) | async function runPostProcessGuardrail(req, res) {
FILE: source/lambda/fulfillment/lib/middleware/5_assemble.js
function sms_hint (line 13) | function sms_hint(req, res) {
function split_message (line 29) | function split_message(message) {
function connect_response (line 38) | async function connect_response(req, res) {
function resetAttributes (line 88) | function resetAttributes(req, res) {
FILE: source/lambda/fulfillment/lib/middleware/7_userInfo.js
function getDistinctValues (line 13) | function getDistinctValues(list, objectId, sortField) {
function update_userInfo (line 24) | async function update_userInfo(res) {
FILE: source/lambda/fulfillment/lib/middleware/alexa.js
function get_welcome_message (line 10) | async function get_welcome_message(req, locale) {
function get_stop_message (line 17) | async function get_stop_message(req, locale) {
function createResObject (line 130) | function createResObject(response, request, subTitle, plainMessage) {
function End (line 158) | function End() {
function AlexaMessage (line 162) | function AlexaMessage(message, endSession) {
function Respond (line 181) | function Respond(message) {
FILE: source/lambda/fulfillment/lib/middleware/jwt.js
function getSigningKey (line 30) | async function getSigningKey(kid, url) {
function verifyToken (line 44) | function verifyToken(idtoken, signingKey) {
FILE: source/lambda/fulfillment/lib/middleware/lex.js
function isConnectClient (line 11) | function isConnectClient(req) {
function isConnectClientChat (line 15) | function isConnectClientChat(req) {
function isConnectClientVoice (line 19) | function isConnectClientVoice(req) {
function isElicitResponse (line 23) | function isElicitResponse(request, response) {
function trapIgnoreWords (line 41) | function trapIgnoreWords(req, transcript) {
function parseLexV2Event (line 59) | function parseLexV2Event(event) {
function filterButtons (line 125) | function filterButtons(response) {
function slackifyResponse (line 143) | function slackifyResponse(response) {
function isCard (line 166) | function isCard(card) {
function isInteractiveMessage (line 170) | function isInteractiveMessage(response) {
function buildResponseCard (line 174) | function buildResponseCard(response) {
function buildImageResponseCardV2 (line 191) | function buildImageResponseCardV2(response) {
function buildInteractiveMessageElements (line 211) | function buildInteractiveMessageElements(elements) {
function buildInteractiveMessageTemplate (line 215) | function buildInteractiveMessageTemplate(response) {
function buildV2InteractiveMessageResponse (line 250) | function buildV2InteractiveMessageResponse(request, response) {
function copyResponseCardtoSessionAttribute (line 259) | function copyResponseCardtoSessionAttribute(response) {
function applyLexResponseCardButtonLimits (line 277) | function applyLexResponseCardButtonLimits(request, response) {
function applyConnectInteractiveMessageButtonLimits (line 298) | function applyConnectInteractiveMessageButtonLimits(response) {
function getV2CloseTemplate (line 315) | function getV2CloseTemplate(request, response) {
function getV2ElicitTemplate (line 336) | function getV2ElicitTemplate(request, response) {
function getV2DialogCodeHookResponseTemplate (line 356) | function getV2DialogCodeHookResponseTemplate(request, response) {
function assembleLexV2Response (line 374) | function assembleLexV2Response(request, response) {
FILE: source/lambda/fulfillment/lib/middleware/lexRouter.js
constant FREE_TEXT_ELICIT_RESPONSE_NAME (line 16) | const FREE_TEXT_ELICIT_RESPONSE_NAME = 'QNAFreeText';
function isConnectClient (line 41) | function isConnectClient(req) {
function translate_res (line 45) | async function translate_res(req, res) {
function lexV2ClientRequester (line 93) | function lexV2ClientRequester(params) {
function mapFromSimpleName (line 108) | function mapFromSimpleName(botName) {
function getFreeTextResponse (line 113) | function getFreeTextResponse(inputText, sentiment, sentimentScore) {
function getRespText (line 129) | function getRespText(req, botName) {
function isDate (line 148) | function isDate(botName, progress) {
function isPhoneNumber (line 152) | function isPhoneNumber(botName, progress) {
function isConnectClientConfirmIntent (line 156) | function isConnectClientConfirmIntent(req, botName, progress) {
function handleRequest (line 169) | async function handleRequest(req, res, botName, botAlias) {
function indicateFailure (line 220) | function indicateFailure(req, res, errmsg) {
function processResponse (line 246) | async function processResponse(req, res, hook, msg) {
FILE: source/lambda/fulfillment/lib/middleware/multilanguage.js
function get_userLanguages (line 15) | async function get_userLanguages(inputText) {
function get_terminologies (line 24) | async function get_terminologies(sourceLang) {
function get_translation (line 34) | async function get_translation(inputText, sourceLang, targetLang, req) {
function set_userLocale (line 68) | function set_userLocale(Languages, userPreferredLocale, defaultConfidenc...
function set_translated_transcript (line 119) | async function set_translated_transcript(locale, req) {
function set_multilang_env (line 151) | async function set_multilang_env(req) {
FILE: source/lambda/fulfillment/lib/middleware/sentiment.js
function get_sentiment_from_comprehend (line 12) | async function get_sentiment_from_comprehend(utterance) {
FILE: source/lambda/fulfillment/lib/middleware/specialtyBotRouter.js
constant DEFAULT_SPECIALTY_BOT_RECEIVING_NAMESPACE (line 21) | const DEFAULT_SPECIALTY_BOT_RECEIVING_NAMESPACE = 'specialtyBotSessionAt...
function getBotUserId (line 28) | function getBotUserId(req) {
function isString (line 39) | function isString(val) {
function extractSSMLContent (line 48) | function extractSSMLContent(ssml) {
function batchTagTranslation (line 60) | async function batchTagTranslation(res, responseLangCode, locale, req) {
function translate_res (line 83) | async function translate_res(req, res) {
function lambdaClientRequester (line 149) | async function lambdaClientRequester(name, req) {
function lexV2ClientRequester (line 170) | function lexV2ClientRequester(params) {
function generateMergedAttributes (line 186) | function generateMergedAttributes(req) {
function mapFromSimpleName (line 198) | function mapFromSimpleName(botName) {
function handleRequest (line 212) | async function handleRequest(req, res, botName) {
function processLexV2Response (line 253) | async function processLexV2Response(params, res) {
function getDialogState (line 285) | function getDialogState(lexv2response) {
function endUseOfSpecialtyBot (line 302) | function endUseOfSpecialtyBot(req, res, welcomeBackMessage) {
function mergeAttributesToReceive (line 339) | function mergeAttributesToReceive(req, res, botResp) {
function processAttributesContext (line 357) | function processAttributesContext(attr, botResp, res, namespace, attribu...
function processBotRespMessage (line 400) | function processBotRespMessage(botResp, req, res, _preferredResponseType) {
function processAttributes (line 421) | function processAttributes(botResp, originalAppContext, res, originalMes...
function getRespCard (line 472) | function getRespCard(botResp) {
function processResponse (line 485) | async function processResponse(req, res, hook) {
FILE: source/lambda/fulfillment/lib/middleware/util.js
function Respond (line 63) | function Respond(message) {
function AlexaError (line 68) | function AlexaError(errormessage) {
function LexError (line 87) | function LexError(errormessage) {
FILE: source/lambda/fulfillment/lib/router/index.js
method constructor (line 10) | constructor() {
method start (line 14) | async start(event) {
method _walk (line 32) | async _walk(req, res = {}, index = 0) {
method add (line 44) | add(fnc) {
FILE: source/lambda/genesys/index.js
function createCallFlowLexV2 (line 23) | async function createCallFlowLexV2() {
FILE: source/lambda/import/convert-xlsx.js
constant XLSX (line 6) | const XLSX = require('read-excel-file/node');
function addDotProperties (line 63) | function addDotProperties(question) {
function addQuestionCard (line 82) | function addQuestionCard(question) {
function mapProperties (line 101) | function mapProperties(headerMapping, question) {
function mapQuestions (line 115) | function mapQuestions(headerRow, question) {
function extractUserQuestions (line 123) | function extractUserQuestions(question) {
function questionIsValid (line 143) | function questionIsValid(question, excelRowNumber) {
function processButtons (line 184) | function processButtons(question) {
FILE: source/lambda/import/delete_existing_content.js
function delete_existing_content (line 20) | async function delete_existing_content(esindex, config, ES_formatted_con...
FILE: source/lambda/import/index.js
function get_settings (line 20) | async function get_settings() {
function es_store_doc (line 37) | async function es_store_doc(index, id, body) {
function isCompleteChar (line 48) | function isCompleteChar(str, pos) {
function processQuestionArray (line 209) | async function processQuestionArray(buffer, response, s3, s3Params) {
function processQuestionObjects (line 247) | async function processQuestionObjects(objects, settings, esindex, config) {
function handleQuestionByType (line 290) | async function handleQuestionByType(obj, settings) {
function handleEmbeddings (line 321) | async function handleEmbeddings(obj, settings) {
function stringifySessionAttributes (line 347) | function stringifySessionAttributes(obj) {
function getOsIndex (line 356) | function getOsIndex(Key) {
FILE: source/lambda/js_lambda_hook_sdk/lambda_hook_sdk/hooks.js
method get_step (line 16) | get_step(event) {
method get_user_attribute (line 20) | get_user_attribute(event, property, default_value = undefined) {
method list_user_attributes (line 24) | list_user_attributes(event) {
method add_user_attribute (line 34) | add_user_attribute(event, key, value) {
method list_settings (line 41) | list_settings(event) {
method get_setting (line 45) | get_setting(event, setting) {
method list_response_card_buttons (line 49) | list_response_card_buttons(event) {
method get_args (line 53) | get_args(event) {
method get_message (line 69) | get_message(event) {
method set_message (line 77) | set_message(event, message) {
method get_es_result (line 83) | get_es_result(event) {
method get_answer_source (line 87) | get_answer_source(event) {
method list_session_attributes (line 91) | list_session_attributes(event) {
method add_session_attribute (line 100) | add_session_attribute(event, key, value) {
method add_response_card_button (line 107) | add_response_card_button(event, text, value, isQID = false, prepend = fa...
method get_lex_event (line 126) | get_lex_event(event) {
method get_bot (line 130) | get_bot(event) {
method get_question (line 134) | get_question(event) {
method get_sentiment (line 138) | get_sentiment(event) {
method set_response_card_imageurl (line 145) | set_response_card_imageurl(event, url) {
method get_response_card_imageurl (line 149) | get_response_card_imageurl(event) {
method set_response_card_title (line 153) | set_response_card_title(event, title, overwrrite = true) {
method validate_response (line 161) | validate_response(event) {
FILE: source/lambda/kendra-webcrawler-schedule-updater/kendra_webcrawler_schedule_updater.py
function create_cron_expression (line 26) | def create_cron_expression(schedule):
function handler (line 67) | def handler(event, context): # NOSONAR Lambda handler
function get_settings (line 104) | def get_settings():
function get_data_source_id (line 134) | def get_data_source_id(index_id, data_source_name):
function get_data_source_schedule (line 145) | def get_data_source_schedule(index_id, datasource_id):
function kendra_update_data_source (line 150) | def kendra_update_data_source(index_id, data_source_id, urls, role_arn, ...
function kendra_supported_languages (line 175) | def kendra_supported_languages(language):
FILE: source/lambda/kendra-webcrawler-schedule-updater/test/conftest.py
function aws_environment_variables (line 10) | def aws_environment_variables():
FILE: source/lambda/kendra-webcrawler-schedule-updater/test/test_lambda_function.py
class TestLambdaFunction (line 15) | class TestLambdaFunction(unittest.TestCase):
method putDynamoDB (line 16) | def putDynamoDB(self, settings_object, dynamodb_client):
method setUp (line 45) | def setUp(self):
method test_update_schedule_changed_success (line 78) | def test_update_schedule_changed_success(self):
method test_update_no_schedule_change (line 103) | def test_update_no_schedule_change(self):
method test_lambda_invalid_schedule_exception (line 120) | def test_lambda_invalid_schedule_exception(self):
FILE: source/lambda/kendra-webcrawler-status/kendra_webcrawler_status.py
class CrawlerException (line 23) | class CrawlerException(Exception):
function handler (line 26) | def handler(event, context): # NOSONAR Need these 2 params
function get_settings (line 49) | def get_settings():
function get_data_source_id (line 78) | def get_data_source_id(index_id, data_source_name):
function kendra_list_data_source_sync_jobs (line 94) | def kendra_list_data_source_sync_jobs(index_id, data_source_id):
FILE: source/lambda/kendra-webcrawler-status/test/conftest.py
function aws_environment_variables (line 10) | def aws_environment_variables():
FILE: source/lambda/kendra-webcrawler-status/test/test_lambda_function.py
class TestLambdaFunction (line 15) | class TestLambdaFunction(unittest.TestCase):
method putDynamoDB (line 16) | def putDynamoDB(self, settings_object, dynamodb_client):
method setUp (line 45) | def setUp(self):
method test_handler_get_status (line 76) | def test_handler_get_status(self):
method test_handler_get_status_data_source_not_found (line 109) | def test_handler_get_status_data_source_not_found(self):
method test_get_settings_parameter_not_found (line 115) | def test_get_settings_parameter_not_found(self):
method test_handler_exception_throttling (line 131) | def test_handler_exception_throttling(self):
FILE: source/lambda/kendra-webcrawler/kendra_webcrawler.py
function create_cron_expression (line 26) | def create_cron_expression(schedule):
function describe_data_source (line 70) | def describe_data_source (data_source_id, index_id):
function get_data_source_status (line 85) | def get_data_source_status (data_source_id, index_id):
function handler (line 94) | def handler(event, context): # NOSONAR Lambda handler
function get_settings (line 136) | def get_settings():
function get_data_source_id (line 167) | def get_data_source_id(index_id, data_source_name):
function kendra_create_data_source (line 179) | def kendra_create_data_source(client, index_id, name, type, role_arn, de...
function kendra_sync_data_source (line 206) | def kendra_sync_data_source(index_id, data_source_id):
function kendra_update_data_source (line 215) | def kendra_update_data_source(index_id, data_source_id, urls, role_arn, ...
function create_dashboard (line 240) | def create_dashboard(index_id, data_source_id):
function kendra_supported_languages (line 258) | def kendra_supported_languages(language):
FILE: source/lambda/kendra-webcrawler/test/conftest.py
function aws_environment_variables (line 11) | def aws_environment_variables():
FILE: source/lambda/kendra-webcrawler/test/test_lambda_function.py
class TestLambdaFunction (line 14) | class TestLambdaFunction(unittest.TestCase):
method putDynamoDB (line 15) | def putDynamoDB(self, settings_object, dynamodb_client):
method setUp (line 42) | def setUp(self):
method test_handler_create_datasource_success (line 74) | def test_handler_create_datasource_success(self):
method test_handler_create_datasource_failed (line 90) | def test_handler_create_datasource_failed(self):
method test_handler_update_datasource_success (line 103) | def test_handler_update_datasource_success(self):
method test_handler_update_datasource_failed (line 116) | def test_handler_update_datasource_failed(self):
method test_create_cron_expression (line 131) | def test_create_cron_expression(self):
method describe_data_source_mock (line 138) | def describe_data_source_mock(self, **kwargs):
FILE: source/lambda/lexv2-build/handler.py
function status (line 159) | def status(status):
function get_qna_v2_slot_type_values (line 167) | def get_qna_v2_slot_type_values(locale_id, utterances):
function get_qid_v2_slot_type_values (line 179) | def get_qid_v2_slot_type_values(locale_id, slot_type_def):
function get_slot_type_id_v2 (line 211) | def get_slot_type_id_v2(slot_type_name, bot_id, bot_version, locale_id):
function get_slot_id (line 234) | def get_slot_id(slot_name, intent_id, bot_id, bot_version, locale_id):
function get_slot_ids (line 258) | def get_slot_ids(intent_id, bot_id, bot_version, locale_id):
function delete_slots_for_intent (line 269) | def delete_slots_for_intent(intent_id, bot_id, bot_version, locale_id):
function get_bot_id (line 284) | def get_bot_id(bot_name):
function get_intent_id (line 305) | def get_intent_id(intent_name, bot_id, bot_version, locale_id):
function add_spantag_to_slots (line 328) | def add_spantag_to_slots(utterance):
function remove_spantag_from_slots (line 334) | def remove_spantag_from_slots(utterance):
function translate_text (line 340) | def translate_text(locale_id, text):
function translate_list (line 362) | def translate_list(locale_id, utterances):
function lex_v2_qna_slot_type (line 374) | def lex_v2_qna_slot_type(slot_type_name, bot_id, bot_version, locale_id,...
function qid_2_slot_type (line 395) | def qid_2_slot_type(qid):
function slot_type_2_qid (line 398) | def slot_type_2_qid(slot_type):
function lex_v2_qid_slot_type (line 401) | def lex_v2_qid_slot_type(qid, bot_id, bot_version, locale_id, slot_type_...
function get_qid_slot_types_to_delete (line 426) | def get_qid_slot_types_to_delete(slot_types, bot_id, bot_version, locale...
function lex_v2_qid_delete_slot_types (line 452) | def lex_v2_qid_delete_slot_types(slot_types, bot_id, bot_version, bot_lo...
function lex_v2_intent_slot (line 464) | def lex_v2_intent_slot(slot_name, intent_id, slot_type_id, slot_sample_u...
function lex_v2_qna_intent (line 508) | def lex_v2_qna_intent(intent_name, slot_type_name, bot_id, bot_version, ...
function qid_2_intent_name (line 547) | def qid_2_intent_name(qid):
function intent_name_2_qid (line 550) | def intent_name_2_qid(intentname):
function lex_v2_qid_intent (line 553) | def lex_v2_qid_intent(qid, utterances, slots, slot_types, bot_id, bot_ve...
function get_slot_type_id_built_in (line 610) | def get_slot_type_id_built_in(qid, slot_types, bot_id, bot_version, loca...
function get_qid_intents_to_delete (line 626) | def get_qid_intents_to_delete(intents, bot_id, bot_version, locale_id):
function lex_v2_qid_delete_intents (line 652) | def lex_v2_qid_delete_intents(intents, bot_id, bot_version, bot_locale_id):
function lex_v2_genesys_intent (line 663) | def lex_v2_genesys_intent(bot_id, bot_version, locale_id):
function lex_v2_fallback_intent (line 698) | def lex_v2_fallback_intent(bot_id, bot_version, locale_id):
function get_bot_locale_status (line 715) | def get_bot_locale_status(bot_id, bot_version, locale_id):
function wait_for_lex_v2_qna_locale (line 725) | def wait_for_lex_v2_qna_locale(bot_id, bot_version, locale_id):
function locale_id_exists (line 735) | def locale_id_exists(bot_id, bot_version, locale_id):
function lex_v2_qna_locale (line 746) | def lex_v2_qna_locale(bot_id, bot_version, locale_id, voice_id, engine):
function get_or_create_lex_v2_service_linked_role (line 762) | def get_or_create_lex_v2_service_linked_role(bot_name):
function get_bot_status (line 782) | def get_bot_status(bot_id):
function wait_for_lex_v2_qna_bot (line 788) | def wait_for_lex_v2_qna_bot(bot_id):
function lex_v2_qna_bot (line 797) | def lex_v2_qna_bot(bot_name):
function get_bot_version_status (line 817) | def get_bot_version_status(bot_id, bot_version):
function wait_for_lex_v2_qna_version (line 826) | def wait_for_lex_v2_qna_version(bot_id, bot_version):
function lex_v2_qna_version (line 841) | def lex_v2_qna_version(bot_id, bot_draft_version, bot_locale_ids):
function get_bot_alias_id (line 859) | def get_bot_alias_id(bot_id, bot_alias_name):
function get_bot_alias_status (line 870) | def get_bot_alias_status(bot_id, bot_alias_id):
function wait_for_lex_v2_qna_alias (line 879) | def wait_for_lex_v2_qna_alias(bot_id, bot_alias_id):
function lex_v2_qna_alias (line 888) | def lex_v2_qna_alias(bot_id, bot_version, bot_alias_name, bot_locale_ids...
function build_lex_v2_qna_bot_locale (line 923) | def build_lex_v2_qna_bot_locale(bot_id, bot_version, locale_id):
function lex_v2_qna_delete_old_versions (line 931) | def lex_v2_qna_delete_old_versions(bot_id):
function batches (line 952) | def batches(lst, n):
function get_bot_info (line 957) | def get_bot_info():
function build_all (line 971) | def build_all(intents, slot_types={}):
function update_bot_locale (line 1006) | def update_bot_locale(intents, slot_types, bot_id, bot_locale_id):
function delete_all (line 1026) | def delete_all():
function process_slot_types (line 1036) | def process_slot_types(items):
function duplicate_utterances (line 1042) | def duplicate_utterances(items):
function replace_with_lex_slot_references (line 1061) | def replace_with_lex_slot_references(qna_intent_utterances, qid_intent_u...
function validate_slots (line 1076) | def validate_slots(intents):
function get_bad_slots (line 1085) | def get_bad_slots(intents):
function build_slot_dict (line 1099) | def build_slot_dict(intents, qid):
function process_intents (line 1106) | def process_intents(items):
function create_bot (line 1138) | def create_bot(event, _):
function update_bot (line 1146) | def update_bot(event, _):
function delete_bot (line 1152) | def delete_bot(event, _):
function handler (line 1157) | def handler(event, context):
FILE: source/lambda/lexv2-build/test/conftest.py
function aws_environment_variables (line 10) | def aws_environment_variables():
FILE: source/lambda/lexv2-build/test/test_lambda_function.py
class TestLambdaFunction (line 13) | class TestLambdaFunction(unittest.TestCase):
method setUp (line 14) | def setUp(self):
method create_lambda_event (line 38) | def create_lambda_event(self, request_type):
method test_lambda_handler (line 51) | def test_lambda_handler(self, cr_helper_mock):
method test_create_bot_success (line 58) | def test_create_bot_success(self, translate_client_mock):
method test_create_bot_invalid_bot_status_exception (line 80) | def test_create_bot_invalid_bot_status_exception(self):
method test_create_bot_version_not_found (line 89) | def test_create_bot_version_not_found(self, translate_client_mock):
method test_lambda_not_called_from_CF_success (line 107) | def test_lambda_not_called_from_CF_success(self, translate_client_mock):
method test_lambda_not_called_from_CF_enable_qid_intent_success (line 131) | def test_lambda_not_called_from_CF_enable_qid_intent_success(self):
method test_lambda_not_called_from_CF_enable_slot_type_success (line 159) | def test_lambda_not_called_from_CF_enable_slot_type_success(self, tran...
method test_delete_bot (line 181) | def test_delete_bot(self):
method test_update_bot (line 187) | def test_update_bot(self, cr_helper_mock):
method list_intent_mock_update (line 201) | def list_intent_mock_update(self, **kwargs):
method list_intent_mock (line 209) | def list_intent_mock(self, **kwargs):
method create_intent_mock (line 215) | def create_intent_mock(self, **kwargs):
method list_slot_types_mock (line 218) | def list_slot_types_mock(self, **kwargs):
method list_slots_mock (line 228) | def list_slots_mock(self, **kwargs):
method describe_bot_locale_mock (line 240) | def describe_bot_locale_mock(self, **kwargs):
FILE: source/lambda/q-business-lambda-hook/q_business_lambda_hook.py
function get_amazonq_response (line 22) | def get_amazonq_response(prompt, context, attachments, qbusiness_client):
function get_settings_from_lambdahook_args (line 51) | def get_settings_from_lambdahook_args(event):
function get_args_from_lambdahook_args (line 64) | def get_args_from_lambdahook_args(event):
function get_s3_file (line 77) | def get_s3_file(s3_path):
function get_attachments (line 86) | def get_attachments(event):
function format_response (line 100) | def format_response(event, amazonq_response):
function format_show_context (line 141) | def format_show_context(amazonq_response):
function format_show_source_links (line 156) | def format_show_source_links(amazonq_response):
function get_idc_iam_credentials (line 166) | def get_idc_iam_credentials(jwt):
function lambda_handler (line 195) | def lambda_handler(event, context): # NOSONAR Lambda Handler
FILE: source/lambda/qnabot-common-layer/qnabot/logging.js
function filter_comprehend_pii (line 13) | function filter_comprehend_pii(text) {
function filter (line 27) | function filter(text) {
function isPIIDetected (line 58) | async function isPIIDetected(text, useComprehendForPII, piiRegex, pii_en...
function setPIIRedactionEnvironmentVars (line 72) | async function setPIIRedactionEnvironmentVars(text, useComprehendForPII,...
function _getPIIEntities (line 88) | async function _getPIIEntities(params) {
function filterFoundEntities (line 102) | function filterFoundEntities(comprehendResult, entity_allow_list, compre...
function _detectPii (line 106) | async function _detectPii(text, useComprehendForPII, piiRegex, pii_rejec...
method log (line 144) | log(...messages) {
method warn (line 147) | warn(...messages) {
method error (line 150) | error(...messages) {
method debug (line 153) | debug(...messages) {
FILE: source/lambda/qnabot-common-layer/qnabot/settings.js
constant EMPTY_SENTINEL (line 14) | const EMPTY_SENTINEL = 'EMPTY_STRING_BY_USER';
function str2bool (line 21) | function str2bool(settings) {
function str2int (line 37) | function str2int(settings) {
function get_parameter (line 56) | async function get_parameter(param_name) {
function getSettings (line 75) | async function getSettings() {
function set_environment_variables (line 115) | function set_environment_variables(settings) {
FILE: source/lambda/s3-clean/lambda_function.py
function delete_bucket_objects (line 20) | def delete_bucket_objects(event, _):
function no_op (line 84) | def no_op(_, __):
function delete_bucket (line 88) | def delete_bucket(event, _):
function poll_delete_bucket (line 97) | def poll_delete_bucket(event, _):
function handler (line 105) | def handler(event, context):
FILE: source/lambda/s3-clean/test/conftest.py
function aws_environment_variables (line 10) | def aws_environment_variables():
FILE: source/lambda/s3-clean/test/test_lambda_function.py
function mocked_cf_event (line 15) | def mocked_cf_event(*args, **kwargs):
function mocked_cf_event_no_prefix (line 23) | def mocked_cf_event_no_prefix(*args, **kwargs):
function mocked_cf_event_non_existent_bucket (line 30) | def mocked_cf_event_non_existent_bucket(*args, **kwargs):
class LambdaTest (line 38) | class LambdaTest(unittest.TestCase):
method setUp (line 40) | def setUp(self):
method add_objects (line 52) | def add_objects(self):
method add_lots_of_object_versions (line 66) | def add_lots_of_object_versions(self):
method add_lots_of_objects (line 76) | def add_lots_of_objects(self):
method test_no_op (line 86) | def test_no_op(self):
method test_delete_bucket_prefix (line 95) | def test_delete_bucket_prefix(self):
method test_delete_bucket (line 105) | def test_delete_bucket(self):
method test_delete_non_existent_bucket (line 115) | def test_delete_non_existent_bucket(self):
method test_delete_empty_bucket (line 124) | def test_delete_empty_bucket(self):
method test_poll_delete_bucket_prefix (line 133) | def test_poll_delete_bucket_prefix(self):
method test_poll_delete_bucket (line 146) | def test_poll_delete_bucket(self):
method test_poll_delete_lots_of_versions (line 159) | def test_poll_delete_lots_of_versions(self):
method test_poll_delete_lots_of_objects (line 172) | def test_poll_delete_lots_of_objects(self):
method test_poll_delete_empty_bucket (line 190) | def test_poll_delete_empty_bucket(self):
FILE: source/lambda/solution-helper/lambda_function.py
function get_parameter (line 37) | def get_parameter(parameter_name):
function get_settings (line 52) | def get_settings():
function update_parameter (line 84) | def update_parameter(parameter_name, new_parameter_value):
function _sanitize_data (line 100) | def _sanitize_data(resource_properties):
function custom_map (line 111) | def custom_map(settings):
function custom_resource (line 151) | def custom_resource(event, _):
function send_metrics_request (line 188) | def send_metrics_request(metrics_data, solution_id, solution_uuid):
function handler (line 204) | def handler(event, context):
FILE: source/lambda/solution-helper/test/conftest.py
function aws_environment_variables (line 10) | def aws_environment_variables():
FILE: source/lambda/solution-helper/test/test_lambda_function.py
function mocked_requests_post (line 79) | def mocked_requests_post(*args, **kwargs):
class LambdaTest (line 87) | class LambdaTest(unittest.TestCase):
method setUp (line 89) | def setUp(self):
method tearDown (line 130) | def tearDown(self):
method test_create_unique_id (line 132) | def test_create_unique_id(self):
method test_send_metrics_successful (line 144) | def test_send_metrics_successful(self, mock_post):
method test_send_metrics_connection_error (line 197) | def test_send_metrics_connection_error(self, mock_post):
method test_send_metrics_other_error (line 216) | def test_send_metrics_other_error(self, mock_post):
method test_sanitize_data (line 234) | def test_sanitize_data(self):
method test_send_metrics_successful_when_event (line 255) | def test_send_metrics_successful_when_event(self, mock_post):
method test_get_settings_parameter_not_found (line 297) | def test_get_settings_parameter_not_found(self):
method test_update_parameter_not_found (line 308) | def test_update_parameter_not_found(self):
FILE: source/lambda/testall/index.js
function getStatusAndStartNextStep (line 35) | async function getStatusAndStartNextStep(Bucket, Key, VersionId, nextSte...
FILE: source/lambda/testall/lib/lex.js
constant MAX_EXECUTION_TIME_MS (line 13) | const MAX_EXECUTION_TIME_MS = 870000;
function processRecognizeText (line 15) | async function processRecognizeText(topic, token, question, locale, exp_...
function processWithLex (line 35) | async function processWithLex(data, filter, token, locale) {
FILE: source/lambda/testall/lib/start.js
function query (line 28) | function query(filter) {
FILE: source/lambda/testall/test/index.fixtures.js
function mockStream (line 10) | function mockStream(config, s3Mock, payload = "") {
FILE: source/lambda/testall/test/index.test.js
function generateConfigAndVersionId (line 39) | function generateConfigAndVersionId(currentStatus) {
function initializeStartStepMocks (line 45) | function initializeStartStepMocks() {
function initializeInProgressStepMocks (line 66) | function initializeInProgressStepMocks(startVersionId) {
function initializeLexStepMocks (line 87) | function initializeLexStepMocks(inProgressVersionId) {
function initializeCleanStepMocks (line 108) | function initializeCleanStepMocks(lexVersionId) {
FILE: source/lambda/testall/test/lib/lex.fixtures.js
function lexQaResponse (line 54) | function lexQaResponse() {
FILE: source/lambda/warmer/lib/index.js
method perform (line 97) | async perform(event, context) {
FILE: source/templates/dev/__tests__/bucket.test.js
function create (line 9) | function create(filename) {
FILE: source/templates/dev/__tests__/dev.test.js
function create (line 8) | function create(filename) {
FILE: source/templates/dev/__tests__/masterConfig.test.js
function create (line 9) | function create(filename) {
FILE: source/templates/dev/__tests__/masterNoConfig.test.js
function create (line 9) | function create(filename) {
FILE: source/templates/dev/bootstrap/handler.js
constant SUCCESS (line 17) | const SUCCESS = 'SUCCESS';
constant FAILED (line 18) | const FAILED = 'FAILED';
function send (line 22) | function send(event, context, responseStatus, responseData, physicalReso...
function Delete (line 68) | async function Delete(params) {
FILE: source/templates/dev/bootstrap/index.test.js
function create (line 6) | function create() {
FILE: source/templates/examples/examples/cfn.js
function sendCfnResponse (line 13) | async function sendCfnResponse(event, context, status) {
function uploadExamples (line 29) | async function uploadExamples(bucket) {
FILE: source/templates/examples/examples/index.js
function jslambda (line 362) | function jslambda(name) {
function pylambda (line 418) | function pylambda(name) {
function jsLambdaLogGroup (line 473) | function jsLambdaLogGroup(name) {
function pyLambdaLogGroup (line 501) | function pyLambdaLogGroup(name) {
FILE: source/templates/examples/examples/js/Quiz.js
function getPrevDoc (line 158) | async function getPrevDoc(event, quizBot) {
function getNextDoc (line 173) | async function getNextDoc(event, quizBot) {
function render (line 188) | function render(event, params) {
function clear (line 198) | function clear(event) {
function isCorrect (line 203) | function isCorrect(response, correct, incorrect) {
function standardize (line 218) | function standardize(str) {
FILE: source/templates/examples/examples/py/BotBroker.py
function handler (line 22) | def handler(event, context): # NOSONAR Lambda Handler
function build_event_from_response (line 49) | def build_event_from_response(event, response):
function middleman (line 73) | def middleman(event, initial_connection):
FILE: source/templates/examples/examples/py/ConnectCallback.py
function handler (line 15) | def handler(event, context): # NOSONAR Lambda Handler
FILE: source/templates/examples/examples/py/Feedback.py
function handler (line 18) | def handler(event, context): # NOSONAR Lambda Handler
function log_feedback (line 64) | def log_feedback(qid, question, feedback_arg, user_info):
function send_feedback_notification (line 82) | def send_feedback_notification(qid, question, feedback_arg, user_info):
function submit_feedback_for_kendra (line 107) | def submit_feedback_for_kendra(kendra_index_id, kendra_query_id, kendra_...
FILE: source/templates/examples/examples/py/Next.py
function handler (line 21) | def handler(event, context): # NOSONAR Lambda Handler
function qid_lambda (line 79) | def qid_lambda(event,next_qid):
function map_to_arn (line 93) | def map_to_arn(name,stack):
function update_lambda_hook (line 108) | def update_lambda_hook(event,hook_event,response):
function build_card_from_response (line 130) | def build_card_from_response(event, response):
function update_result (line 150) | def update_result(event, response):
FILE: source/templates/examples/examples/py/Previous.py
function handler (line 21) | def handler(event, context): # NOSONAR Lambda Handler
function map_to_arn (line 81) | def map_to_arn(name,stack):
function update_lambda_hook (line 96) | def update_lambda_hook(event,hook_event,response):
function build_card_from_response (line 108) | def build_card_from_response(event, response):
function update_result (line 128) | def update_result(event, response):
FILE: source/templates/examples/examples/py/__tests__/conftest.py
function aws_environment_variables (line 11) | def aws_environment_variables():
FILE: source/templates/examples/examples/py/__tests__/test_ConnectCallback.py
class TestConnectCallback (line 10) | class TestConnectCallback(unittest.TestCase):
method test_handler (line 12) | def test_handler(self):
method test_handler_with_missing_arguments (line 56) | def test_handler_with_missing_arguments(self):
method test_handler_handles_connect_errors (line 69) | def test_handler_handles_connect_errors(self):
FILE: source/templates/examples/examples/py/__tests__/test_Feedback.py
class TestFeedback (line 10) | class TestFeedback(unittest.TestCase):
method test_handler_positive_feedback (line 12) | def test_handler_positive_feedback(self):
method test_handler_negative_feedback (line 74) | def test_handler_negative_feedback(self):
method test_handler_handles_error (line 140) | def test_handler_handles_error(self):
FILE: source/templates/examples/examples/py/__tests__/test_Next.py
class TestNext (line 10) | class TestNext(unittest.TestCase):
method test_handler (line 12) | def test_handler(self):
method test_handler_with_list_of_next (line 57) | def test_handler_with_list_of_next(self):
method test_handler_with_answer (line 102) | def test_handler_with_answer(self):
method test_handler_with_lambda_invoke (line 152) | def test_handler_with_lambda_invoke(self):
method test_handler_with_no_parent (line 220) | def test_handler_with_no_parent(self):
method test_handler_handles_request_with_no_next (line 288) | def test_handler_handles_request_with_no_next(self):
method test_update_lambda_hook_with_no_previous (line 329) | def test_update_lambda_hook_with_no_previous(self):
method test_update_lambda_hook_with_not_matching_previous (line 377) | def test_update_lambda_hook_with_not_matching_previous(self):
method test_update_lambda_hook_with_long_previous_list (line 424) | def test_update_lambda_hook_with_long_previous_list(self):
method test_build_card_from_response (line 484) | def test_build_card_from_response(self):
method test_update_result (line 509) | def test_update_result(self):
method test_update_result_with_many_previous (line 567) | def test_update_result_with_many_previous(self):
FILE: source/templates/examples/examples/py/__tests__/test_Previous.py
class TestPrevious (line 10) | class TestPrevious(unittest.TestCase):
method test_handler (line 12) | def test_handler(self):
method test_handler_with_lambda_invoke (line 58) | def test_handler_with_lambda_invoke(self):
method test_handler_with_lambda_invoke_answer (line 127) | def test_handler_with_lambda_invoke_answer(self):
method test_handler_handles_request_with_no_previous (line 187) | def test_handler_handles_request_with_no_previous(self):
method test_build_card_from_response (line 227) | def test_build_card_from_response(self):
method test_update_result (line 251) | def test_update_result(self):
method test_update_lambda_hook_with_not_matching_previous (line 309) | def test_update_lambda_hook_with_not_matching_previous(self):
FILE: source/templates/examples/examples/py/__tests__/test_hello.py
class TestHello (line 10) | class TestHello(unittest.TestCase):
method test_returns_morning_greeting (line 12) | def test_returns_morning_greeting(self, datetime_mock):
method test_returns_afternoon_greeting (line 25) | def test_returns_afternoon_greeting(self, datetime_mock):
method test_returns_evening_greeting (line 39) | def test_returns_evening_greeting(self, datetime_mock):
FILE: source/templates/examples/examples/py/hello.py
function handler (line 9) | def handler(event, context): # NOSONAR Lambda Handler
FILE: source/templates/examples/extensions/index.js
function jslambda (line 249) | function jslambda(name) {
function pylambda (line 304) | function pylambda(name) {
function codeVersion (line 358) | function codeVersion(name) {
function lambdaLogGroup (line 370) | function lambdaLogGroup(name) {
FILE: source/templates/examples/extensions/js_lambda_hooks/CreateRecentTopicsResponse/CreateRecentTopicsResponse.js
function create_buttons (line 9) | function create_buttons(event, start = 0, stop = 10) {
FILE: source/templates/examples/extensions/py_lambda_hooks/CustomPYHook/CustomPYHook.py
function handler (line 6) | def handler(event, context): # NOSONAR Lambda Handler
FILE: source/templates/examples/extensions/py_lambda_hooks/CustomPYHook/__tests__/conftest.py
function event (line 11) | def event():
function context (line 20) | def context():
FILE: source/templates/examples/extensions/py_lambda_hooks/CustomPYHook/__tests__/test_CustomPYHook.py
class TestCustomPYHook (line 6) | class TestCustomPYHook():
method test_returns_greeting (line 8) | def test_returns_greeting(self, event, context):
FILE: source/templates/examples/extensions/ui_imports/ui_import.js
function sendCfnResponse (line 15) | async function sendCfnResponse(event, context, status) {
function processFileContent (line 31) | function processFileContent(content, properties) {
function uploadUIImports (line 41) | async function uploadUIImports(bucket, properties) {
FILE: source/templates/examples/index.test.js
function create (line 6) | function create() {
FILE: source/templates/export/index.test.js
function create (line 6) | function create() {
FILE: source/templates/import/index.test.js
function create (line 6) | function create() {
FILE: source/templates/master/cfn/handler.js
constant SUCCESS (line 17) | const SUCCESS = 'SUCCESS';
constant FAILED (line 18) | const FAILED = 'FAILED';
function send (line 22) | async function send(event, context, responseStatus, responseData, physic...
FILE: source/templates/master/config.js
function stage (line 63) | function stage(name) {
FILE: source/templates/master/index.test.js
function create (line 8) | function create() {
FILE: source/templates/master/lambda.js
function permission (line 52) | function permission(name) {
FILE: source/templates/master/lex-build/index.js
function lambda (line 304) | function lambda(code, variable, runtime, loggingConfig) {
FILE: source/templates/master/lexv2-build/index.js
function lambda (line 164) | function lambda(code, variable, runtime, loggingConfig) {
FILE: source/templates/master/opensearch/handler.js
constant SUCCESS (line 17) | const SUCCESS = 'SUCCESS';
constant FAILED (line 18) | const FAILED = 'FAILED';
function send (line 22) | async function send(event, context, responseStatus, responseData, physic...
FILE: source/templates/master/proxy-lex/status.js
function getStatusResponse (line 14) | function getStatusResponse(response, build) {
FILE: source/templates/master/proxy-lex/test.js
method get (line 13) | get(test) {
FILE: source/templates/master/routes/bot/test.js
method path (line 37) | path() {
FILE: source/templates/master/routes/examples/index.js
function proxy (line 211) | function proxy(opts) {
FILE: source/templates/master/routes/examples/test.js
method handler (line 19) | async handler(test) {
method handlerPhoto (line 37) | async handlerPhoto(test) {
FILE: source/templates/master/routes/images.js
function proxy (line 27) | function proxy(opts) {
FILE: source/templates/master/routes/jobs/index.js
function proxy (line 250) | function proxy(opts) {
FILE: source/templates/master/routes/proxy.js
function proxy (line 54) | function proxy(opts) {
FILE: source/templates/master/routes/qa/test.js
function static (line 143) | function static(){
FILE: source/templates/master/signup/message.js
function message (line 8) | function message(code) {
function isEmailApproved (line 12) | function isEmailApproved(email, approvedDomain) {
function setEmailResponse (line 21) | function setEmailResponse(event) {
FILE: source/templates/master/signup/signup.js
function isEmailApproved (line 6) | function isEmailApproved(email, approvedDomain) {
function handleAutoVerify (line 15) | function handleAutoVerify(event) {
FILE: source/templates/public-vpc-support/__tests__/indexConfig.test.js
function create (line 10) | function create(filename) {
FILE: source/templates/public-vpc-support/__tests__/indexNoConfig.test.js
function create (line 9) | function create(filename) {
FILE: source/templates/public/__tests__/indexConfig.test.js
function create (line 10) | function create(filename) {
FILE: source/templates/public/__tests__/indexNoConfig.test.js
function create (line 9) | function create(filename) {
FILE: source/templates/testall/index.test.js
function create (line 6) | function create() {
FILE: source/utility_scripts/configureAlerts.py
function put_alarm_cluster (line 37) | def put_alarm_cluster(domainname, desc, metricname, treatmissingdata, to...
function put_alarm_lambda (line 62) | def put_alarm_lambda(functionname, desc, metricname, threshold, treatmis...
function process_stacks (line 87) | def process_stacks(stackname):
FILE: source/utility_scripts/configureCMK.py
function assign_role (line 71) | def assign_role(role_name):
function put_key_policy (line 90) | def put_key_policy (stackname,roles):
function process_stacks (line 135) | def process_stacks(stackname):
FILE: source/utility_scripts/csv2json_converter/js/qnabot_csv2json_converter.js
constant QUESTION_IDENTIFIER_INDEX (line 10) | let QUESTION_IDENTIFIER_INDEX;
constant QUESTION_TYPE_INDEX (line 11) | let QUESTION_TYPE_INDEX;
constant QUESTION_INDEX (line 12) | let QUESTION_INDEX;
constant QUESTION_ANSWER_INDEX (line 13) | let QUESTION_ANSWER_INDEX;
constant QUESTION_ANSWER_MARKDOWN (line 14) | let QUESTION_ANSWER_MARKDOWN;
function load_csv_file (line 17) | function load_csv_file() {
function convertToQnABotJSON (line 46) | function convertToQnABotJSON(arrCSVInput) {
function checkCSVFileFormat (line 96) | function checkCSVFileFormat(arrFieldHeadersinFile) {
function saveConvertedFile (line 131) | function saveConvertedFile(strJSONOutput) {
function create_QnA_qid (line 148) | function create_QnA_qid(strInputCSVValue) {
function create_QnA_type (line 154) | function create_QnA_type(strInputCSVValue) {
function create_QnA_q (line 160) | function create_QnA_q(strInputCSVValue) {
function create_QnA_a (line 166) | function create_QnA_a(strInputCSVValue) {
function create_QnA_alt_markdown (line 172) | function create_QnA_alt_markdown(strInputCSVValue) {
function updateProgress (line 178) | function updateProgress(strProgressMsg) {
FILE: source/utility_scripts/validate-conditional-chaining.js
constant REPORT_WIDTH (line 27) | const REPORT_WIDTH = 80;
function createGenericContext (line 33) | function createGenericContext() {
function isLambdaExpression (line 50) | function isLambdaExpression(conditionalChaining) {
function validateExpression (line 65) | function validateExpression(expression, qid) {
function validateExportFile (line 90) | function validateExportFile(data) {
function printReport (line 156) | function printReport(results, filePath) {
function processExportFile (line 203) | function processExportFile(filePath) {
function printHelp (line 237) | function printHelp() {
FILE: source/website/__tests__/lib/store/api/actions/index.test.js
class CustomError (line 18) | class CustomError extends Error {
method constructor (line 19) | constructor(message, response, code) {
FILE: source/website/js/admin.js
method install (line 72) | install() {
FILE: source/website/js/client.js
method install (line 50) | install() {
FILE: source/website/js/components/designer/empty.js
function empty (line 6) | function empty(input) {
FILE: source/website/js/lib/client-auth.js
function axiosPost (line 16) | async function axiosPost(axiosMethod, axiosClient, axiosData) {
function getTokens (line 28) | async function getTokens(response, code) {
function refreshTokens (line 50) | async function refreshTokens(response) {
function getIdentityId (line 67) | async function getIdentityId(region, identityPoolId, Logins) {
function getAuthCredentials (line 82) | async function getAuthCredentials(region, identityId, Logins) {
function getCredentials (line 105) | async function getCredentials(region, poolId, login = {}) {
FILE: source/website/js/lib/store/actions.js
method bootstrap (line 10) | async bootstrap(context) {
FILE: source/website/js/lib/store/api/actions/connect.js
method getContactFlow (line 6) | getContactFlow(context, opts) {
FILE: source/website/js/lib/store/api/actions/export.js
constant EMPTY_SENTINEL (line 11) | const EMPTY_SENTINEL = 'EMPTY_STRING_BY_USER';
function getParameters (line 13) | async function getParameters(context, dynamodb) {
function listSettings (line 69) | async function listSettings(context) {
method startExport (line 82) | async startExport(context, opts) {
method startKendraSyncExport (line 101) | async startKendraSyncExport(context, opts) {
method downloadExport (line 114) | async downloadExport(context, opts) {
method waitForExport (line 128) | waitForExport(context, opts) {
method listExports (line 154) | async listExports(context, opts) {
method getExport (line 164) | async getExport(context, opts) {
method getExportByJobId (line 170) | async getExportByJobId(context, id) {
method deleteExport (line 176) | async deleteExport(context, opts) {
FILE: source/website/js/lib/store/api/actions/genesys.js
method getGenesysCallFlow (line 6) | getGenesysCallFlow(context, opts) {
FILE: source/website/js/lib/store/api/actions/import.js
method listExamples (line 10) | async listExamples(context) {
method getExampleDescription (line 26) | async getExampleDescription(context, example) {
method startImport (line 34) | async startImport(context, opts) {
method waitForImport (line 50) | waitForImport(context, opts) {
method listImports (line 76) | async listImports(context, opts) {
method getImport (line 86) | getImport(context, opts) {
method deleteImport (line 92) | deleteImport(context, opts) {
method getTerminologies (line 98) | getTerminologies(context, opts) {
method startImportTranslate (line 104) | startImportTranslate(context, opts) {
FILE: source/website/js/lib/store/api/actions/index.js
function handleTimeout (line 15) | function handleTimeout(context, e) {
function handleError (line 29) | function handleError(e, context, opts) {
method botinfo (line 106) | botinfo(context) {
method alexa (line 113) | alexa(context) {
method schema (line 120) | schema(context, body) {
method list (line 127) | list(context, opts) {
method check (line 141) | async check(context, qid) {
method add (line 158) | add(context, payload) {
method update (line 161) | update(context, payload) {
method remove (line 169) | remove(context, qid) {
method removeBulk (line 176) | removeBulk(context, list) {
method removeQuery (line 184) | removeQuery(context, query) {
method build (line 192) | build(context) {
method status (line 200) | status(context) {
method search (line 207) | search(context, opts) {
FILE: source/website/js/lib/store/api/actions/kendraIndex.js
method startKendraV2Indexing (line 8) | startKendraV2Indexing(context, opts) {
method getKendraIndexingStatus (line 14) | getKendraIndexingStatus(context, opts) {
FILE: source/website/js/lib/store/api/actions/settings.js
constant EMPTY_SENTINEL (line 12) | const EMPTY_SENTINEL = 'EMPTY_STRING_BY_USER';
function getParameters (line 644) | async function getParameters(context, dynamodb) {
function saveParameters (line 701) | async function saveParameters(context, dynamodb, settings) {
function checkForRestoredSettings (line 773) | async function checkForRestoredSettings(context, dynamodb, settings){
function createSettingsMap (line 843) | function createSettingsMap(settings) { // NOSONAR - javascript:S3776 - ...
function sendAnonymizedData (line 862) | async function sendAnonymizedData(params, settings){
method listSettings (line 886) | async listSettings(context) {
method listPrivateSettings (line 897) | async listPrivateSettings(context) {
method updateSettings (line 931) | async updateSettings(context, settings) {
method getSettingsMap (line 962) | getSettingsMap() {
FILE: source/website/js/lib/store/api/actions/testall.js
method startTestAll (line 10) | async startTestAll(context, opts) {
method downloadTestAll (line 24) | async downloadTestAll(context, opts) {
method waitForTestAll (line 37) | waitForTestAll(context, opts) {
method listTestAll (line 63) | async listTestAll(context, opts) {
method getTestAll (line 73) | getTestAll(context, opts) {
method deleteTestAll (line 79) | deleteTestAll(context, opts) {
method getBotInfo (line 85) | getBotInfo(context) {
FILE: source/website/js/lib/store/api/actions/tmp.js
function run (line 11) | async function run() {
FILE: source/website/js/lib/store/api/index.js
method loading (line 14) | loading(state, val) {
FILE: source/website/js/lib/store/data/actions/add.js
function next (line 10) | async function next(count, res, rej, context, result) {
method build (line 35) | async build(context) {
method update (line 60) | async update(context, qa) {
method add (line 63) | async add(context, qa) {
function clean (line 69) | function clean(obj) {
FILE: source/website/js/lib/store/data/actions/delete.js
method removeQ (line 11) | async removeQ(context, { index, item }) {
method removeQA (line 20) | async removeQA(context, QA) {
method removeQAs (line 33) | async removeQAs(context, QAs) {
method removeFilter (line 45) | async removeFilter(context) {
FILE: source/website/js/lib/store/data/actions/get.js
method schema (line 11) | async schema(context) {
method botinfo (line 15) | async botinfo(context) {
method search (line 26) | async search(context, opts) {
method get (line 43) | async get(context, opts = {}) {
method getAll (line 63) | async getAll(context) {
FILE: source/website/js/lib/store/data/actions/up-download.js
method download (line 13) | async download(context) {
method downloadLocal (line 27) | downloadLocal(context) {
method downloadSelect (line 40) | async downloadSelect(context) {
method upload (line 55) | async upload(context, params) {
method uploadProcess (line 71) | async uploadProcess(context, { data }) {
method uploadUrl (line 89) | async uploadUrl(context, { url }) {
FILE: source/website/js/lib/store/data/getters.js
method selected (line 7) | selected(state) {
method QAlist (line 10) | QAlist(state, getters, rootGetters) {
FILE: source/website/js/lib/store/data/mutations.js
method close (line 7) | close(store) {
method selectAll (line 27) | selectAll(store, value) {
method setFilter (line 30) | setFilter(store, query) {
method clearFilter (line 33) | clearFilter(store) {
method addQA (line 36) | addQA(state, qa) {
method schema (line 40) | schema(state, schema) {
method delQA (line 43) | delQA(state, QA) {
method clearQA (line 47) | clearQA(state) {
method results (line 50) | results(state, new_results) {
method loading (line 53) | loading(state, val) {
FILE: source/website/js/lib/store/mutations.js
method captureHash (line 7) | captureHash(state) {
method info (line 10) | info(state, payload) {
method bot (line 13) | bot(state, payload) {
method utterances (line 18) | utterances(state, payload) {
method alexa (line 21) | alexa(state, payload) {
method setBotInfo (line 24) | setBotInfo(store, data) {
method setError (line 28) | setError(store, message) {
method clearError (line 31) | clearError(store) {
FILE: source/website/js/lib/store/page/actions.js
method setMode (line 13) | setMode(context, mode) {
method goToPage (line 19) | async goToPage(context, index) {
method nextPage (line 29) | nextPage(context) {
method previousPage (line 35) | previousPage(context) {
FILE: source/website/js/lib/store/page/getters.js
method pages (line 7) | pages(state) {
FILE: source/website/js/lib/store/page/mutations.js
method setMode (line 7) | setMode(store, mode) {
method setPage (line 10) | setPage(store, page) {
method setTotal (line 13) | setTotal(store, total) {
method incrementTotal (line 16) | incrementTotal(store, count) {
method decrementTotal (line 20) | decrementTotal(store, count) {
method toggleMode (line 24) | toggleMode(store, mode) {
method toggleSearch (line 39) | toggleSearch(store) {
method toggleFilter (line 42) | toggleFilter(store) {
FILE: source/website/js/lib/store/user/mutations.js
method credentials (line 10) | credentials(state, payload) {
method login (line 14) | login(state) {
method setId (line 17) | setId(state, Id) {
FILE: source/website/js/lib/validator.js
method validate (line 9) | validate(value) {
method validate (line 23) | validate(value) {
Condensed preview — 1077 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (9,535K chars).
[
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 1174,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\n**Describe the "
},
{
"path": ".github/ISSUE_TEMPLATE/conditional_chaining.md",
"chars": 853,
"preview": "---\nname: Conditional Chaining Expression Request\nabout: Request support for new conditional chaining expressions or ope"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 467,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this solution\ntitle: ''\nlabels: enhancement\nassignees: ''\n\n---\n\n**I"
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 196,
"preview": "*Issue #, if available:*\n\n*Description of changes:*\n\nBy submitting this pull request, I confirm that you can use, modify"
},
{
"path": ".gitignore",
"chars": 1738,
"preview": "build\n\ncodescan-*\n\n# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n*."
},
{
"path": ".nightswatch/functional/conftest.py",
"chars": 7837,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/files/EPCTerminology.csv",
"chars": 59,
"preview": "en,es\nwithout incurring any fees, sin incurrir ningún cargo"
},
{
"path": ".nightswatch/functional/files/import-fail-expected.json",
"chars": 984,
"preview": "{\n \"qna\": [\n {\n \"a\": \"You cannot leave your QID blank\",\n \"type\": \"qna\",\n \"qid\": \"\",\n \"q\": [\n "
},
{
"path": ".nightswatch/functional/files/import-pass-expected.json",
"chars": 1565,
"preview": "{\n \"qna\": [\n {\n \"a\": \"From the import page.\",\n \"r\": {\n \"buttons\": [\n {\n \"text\":"
},
{
"path": ".nightswatch/functional/files/terms.csv",
"chars": 65,
"preview": "en,fr,es\ncustom terminology,custom terminology,custom terminology"
},
{
"path": ".nightswatch/functional/helpers/__init__.py",
"chars": 476,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/bot_intents/get_attribute.json",
"chars": 1058,
"preview": "{\n\t\"intentName\": \"GetAttribute\",\n\t\"localeId\": \"en_US\",\n\t\"sampleUtterances\": [\n\t\t{\n\t\t\t\"utterance\": \"Do I have an attribut"
},
{
"path": ".nightswatch/functional/helpers/bot_intents/greetings.json",
"chars": 696,
"preview": "{\n\t\"intentName\": \"sayHello\",\n\t\"localeId\": \"en_US\",\n\t\"sampleUtterances\": [\n\t\t{\n\t\t\t\"utterance\": \"Hello\"\n\t\t},\n\t\t{\n\t\t\t\"utter"
},
{
"path": ".nightswatch/functional/helpers/bot_intents/set_attribute.json",
"chars": 486,
"preview": "{\n\t\"intentName\": \"SetAttribute\",\n\t\"localeId\": \"en_US\",\n\t\"sampleUtterances\": [\n\t\t{\n\t\t\t\"utterance\": \"Give me an attribute\""
},
{
"path": ".nightswatch/functional/helpers/cfn_parameter_fetcher.py",
"chars": 10206,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/cloud_watch_client.py",
"chars": 2929,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/cognito_client.py",
"chars": 5125,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/iam_client.py",
"chars": 3451,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/kendra_client.py",
"chars": 2526,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/lex_client.py",
"chars": 11103,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/s3_client.py",
"chars": 1712,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/translate_client.py",
"chars": 3379,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/utils/__init__.py",
"chars": 476,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/utils/textbox.py",
"chars": 2076,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/website_model/__init__.py",
"chars": 476,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/website_model/chat_page.py",
"chars": 5073,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/website_model/custom_terminology_page.py",
"chars": 1471,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/website_model/dom_operator.py",
"chars": 12265,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/website_model/edit_page.py",
"chars": 41299,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/website_model/export_page.py",
"chars": 2924,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/website_model/import_page.py",
"chars": 5004,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/website_model/kendra_page.py",
"chars": 2692,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/website_model/login_page.py",
"chars": 3597,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/website_model/menu_nav.py",
"chars": 4934,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/helpers/website_model/settings_page.py",
"chars": 23927,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/pytest.ini",
"chars": 441,
"preview": "[pytest]\nlog_cli = true\nlog_cli_date_format = %Y-%m-%d %H:%M:%S\nlog_cli_format = %(asctime)s %(levelname)s %(message)s\nl"
},
{
"path": ".nightswatch/functional/question_bank/embeddings_questions.json",
"chars": 190,
"preview": "{\n\t\"qna\": [\n\t\t{\n\t\t\t\"a\": \"1600 Pennsylvania Ave., NW, Washington, DC 20500\",\n\t\t\t\"type\": \"qna\",\n\t\t\t\"qid\": \"Embed.001\",\n\t\t\t"
},
{
"path": ".nightswatch/functional/question_bank/guardrail_question.json",
"chars": 199,
"preview": "{\n\t\"qna\": [\n\t\t{\n\t\t\t\"a\": \"The credit card is 1111-1111-1111-1111\",\n\t\t\t\"type\": \"qna\",\n\t\t\t\"qid\": \"Guardrail.001\",\n\t\t\t\"q\": ["
},
{
"path": ".nightswatch/functional/question_bank/import_questions.json",
"chars": 209,
"preview": "{\n \"qna\": [\n {\n \"q\": [\n \"Which file formats are supported by the QnA Bot question designer impor"
},
{
"path": ".nightswatch/functional/question_bank/import_questions_qna.json",
"chars": 2260,
"preview": "{\n \"qna\": [\n {\n \"next\": \"NextQid\",\n \"a\": \"Answer\",\n \"enableQidIntent\": true,\n \"kendr"
},
{
"path": ".nightswatch/functional/question_bank/import_questions_slot.json",
"chars": 403,
"preview": "{\n \"qna\": [\n {\n \"descr\": \"Description\",\n \"resolutionStrategyRestrict\": true,\n \"type\": \"slot"
},
{
"path": ".nightswatch/functional/question_bank/import_questions_text.json",
"chars": 1296,
"preview": "{\n \"qna\": [\n {\n \"passage\": \"Passage\",\n \"kendraRedirectQueryText\": \"KendraRedirect\",\n \"refMa"
},
{
"path": ".nightswatch/functional/question_bank/kendra_questions.json",
"chars": 258,
"preview": "{\n\t\"qna\": [\n\t\t{\n\t\t\t\"a\": \"Check out these links:\",\n\t\t\t\"kendraRedirectQueryText\": \"alexa AND \\\"custom skill\\\"\",\n\t\t\t\"type\""
},
{
"path": ".nightswatch/functional/question_bank/large_import_questions.json",
"chars": 2521055,
"preview": "{\n\t\"qna\": [\n\t\t{\n\t\t\t\"qid\": \"Translate.001\",\n\t\t\t\"type\": \"qna\",\n\t\t\t\"q\": [\"Can you tell me why I should use custom terminolo"
},
{
"path": ".nightswatch/functional/question_bank/llm_questions.json",
"chars": 227,
"preview": "{\n\t\"qna\": [\n\t\t{\n\t\t\t\"passage\": \"Humpty Dumpty sat on the wall, Humpty Dumpty had a great fall, All the king's horses and"
},
{
"path": ".nightswatch/functional/question_bank/question_designer_questions.json",
"chars": 6300,
"preview": "{\n\t\"qna\": [\n\t\t{\n\t\t\t\"qid\": \"Designer.001\",\n\t\t\t\"type\": \"qna\",\n\t\t\t\"q\": [\"What is delicious?\"],\n\t\t\t\"a\": \"candy\"\n\t\t},\n\t\t{\n\t\t\t"
},
{
"path": ".nightswatch/functional/question_bank/routing_questions.json",
"chars": 1442,
"preview": "{\n\t\"qna\": [\n\t\t{\n\t\t\t\"a\": \"One second. Let me get him for you...\",\n\t\t\t\"type\": \"qna\",\n\t\t\t\"qid\": \"Routing.001\",\n\t\t\t\"botRouti"
},
{
"path": ".nightswatch/functional/question_bank/session_attribute_questions.json",
"chars": 807,
"preview": "{\n\t\"qna\": [\n\t\t{\n\t\t\t\"a\": \"I have set \\\"Amazon\\\" as your session attribute.\",\n\t\t\t\"type\": \"qna\",\n\t\t\t\"qid\": \"Session.002\",\n\t"
},
{
"path": ".nightswatch/functional/question_bank/settings_questions.json",
"chars": 224,
"preview": "{\n \"qna\": [\n {\n \"a\": \"You stumped me, I don't currently know the answer to that question.\",\n \"type"
},
{
"path": ".nightswatch/functional/question_bank/translate_questions.json",
"chars": 696,
"preview": "{\n\t\"qna\": [\n\t\t{\n\t\t\t\"qid\": \"Translate.001\",\n\t\t\t\"type\": \"qna\",\n\t\t\t\"q\": [\"Can you tell me why I should use custom terminolo"
},
{
"path": ".nightswatch/functional/test_1_login.py",
"chars": 3426,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/test_2_import.py",
"chars": 10256,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/test_embeddings.py",
"chars": 2748,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/test_export.py",
"chars": 1036,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/test_guardrails.py",
"chars": 4727,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/test_kendra.py",
"chars": 8813,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/test_knowledge_base.py",
"chars": 7149,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/test_lambda_hooks.py",
"chars": 3403,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/test_llm.py",
"chars": 7408,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/test_question_designer.py",
"chars": 23639,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/test_routing.py",
"chars": 7291,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/test_session_attribute.py",
"chars": 4577,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/test_settings.py",
"chars": 4008,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/test_translate.py",
"chars": 8475,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/functional/test_tuning.py",
"chars": 2655,
"preview": "######################################################################################################################\n#"
},
{
"path": ".nightswatch/pyproject.toml",
"chars": 321,
"preview": "[tool.poetry]\nname = \"Functional tests\"\ndescription = \"Functional tests\"\npackage-mode = false\n\n[tool.poetry.dependencies"
},
{
"path": "CHANGELOG.md",
"chars": 60417,
"preview": "# Change Log\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Chang"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 308,
"preview": "## Code of Conduct\nThis project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-condu"
},
{
"path": "CONTRIBUTING.md",
"chars": 3772,
"preview": "# Contributing Guidelines\n\nThank you for your interest in contributing to our project. Whether it's a bug report, new fe"
},
{
"path": "LICENSE.txt",
"chars": 10141,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "NOTICE.txt",
"chars": 75193,
"preview": "qnabot-on-aws\n\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nLicensed under the Apache License Vers"
},
{
"path": "README.md",
"chars": 34198,
"preview": "# QnABot on AWS\n\n## Overview\n\nQnABot on AWS is a multi-channel, multi-language conversational interface (chatbot) that r"
},
{
"path": "SECURITY.md",
"chars": 526,
"preview": "## Reporting Security Issues\n\nWe take all security reports seriously. When we receive such reports,\nwe will investigate "
},
{
"path": "deployment/build-s3-dist.sh",
"chars": 4761,
"preview": "#!/bin/bash\n############################################################################################################"
},
{
"path": "deployment/run-unit-tests.sh",
"chars": 8573,
"preview": "#!/bin/bash\n############################################################################################################"
},
{
"path": "source/.markdownlint.jsonc",
"chars": 40,
"preview": "{\n \"MD033\":false,\n \"MD013\":false\n}"
},
{
"path": "source/.npmrc",
"chars": 18,
"preview": "engine-strict=true"
},
{
"path": "source/.prettierignore",
"chars": 17,
"preview": "node_modules\ntmp\n"
},
{
"path": "source/.prettierrc.yml",
"chars": 158,
"preview": "# .prettierrc or .prettierrc.yaml\nproseWrap: 'preserve'\ntrailingComma: 'none'\ntabWidth: 4\nsemi: true\nsingleQuote: true\nq"
},
{
"path": "source/Makefile",
"chars": 1624,
"preview": "define check_poetry\n $(shell if command -v poetry >/dev/null 2>&1; then \\\n echo \"poetry\"; \\\n elif [ -n \"$(P"
},
{
"path": "source/assets/Makefile",
"chars": 94,
"preview": "DST=../build/assets.zip\n$(DST): ./*\n\techo \"Building Assets\"; zip -FSr -x Makefile -q $(DST) .\n"
},
{
"path": "source/assets/README.md",
"chars": 143,
"preview": "#Assets\nstatic assets.\n\ndefault-utterances.json\n default utterances for lex slot type\n\nexamples/documents\nexample QnA"
},
{
"path": "source/assets/default-utterances.json",
"chars": 21,
"preview": "[\"dummy utterance\"\n]\n"
},
{
"path": "source/assets/examples/README.md",
"chars": 1,
"preview": "\n"
},
{
"path": "source/assets/examples/documents/blog-samples-final.json",
"chars": 9888,
"preview": "{\n \"qna\": [\n {\n \"a\": \"Greetings friendly human! Ask me a question. Try to stump me.\",\n \"qid\": \"BotStyle.0"
},
{
"path": "source/assets/examples/documents/blog-samples-final.txt",
"chars": 39,
"preview": "Ending point for QnABot blog tutorial.\n"
},
{
"path": "source/assets/examples/documents/blog-samples.json",
"chars": 3500,
"preview": "{\n \"qna\": [\n {\n \"qid\": \"QnABot.002\",\n \"q\": [\n \"How do I use Q and A bot\"\n ],\n"
},
{
"path": "source/assets/examples/documents/blog-samples.txt",
"chars": 40,
"preview": "Starting point for QnABot blog tutorial\n"
},
{
"path": "source/assets/examples/photos/README.md",
"chars": 112,
"preview": "# Example images\nfor use in response cards\nmust be SVG images in order to be served correctly from ApiGateway. \n"
},
{
"path": "source/bin/.gitignore",
"chars": 16,
"preview": ".inc.json\n*.log\n"
},
{
"path": "source/bin/README.md",
"chars": 60,
"preview": "# Scripts\nutility scripts for building and launching QNABot\n"
},
{
"path": "source/bin/URL.sh",
"chars": 1473,
"preview": "#! /bin/bash\n__dirname=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd )\"\nexport AWS_PROFILE=$(node -e \"console.log(req"
},
{
"path": "source/bin/build.js",
"chars": 2458,
"preview": "#! /usr/bin/env node\n/** ***********************************************************************************************"
},
{
"path": "source/bin/check.js",
"chars": 3314,
"preview": "#! /usr/bin/env node\n/** ***********************************************************************************************"
},
{
"path": "source/bin/check_bucket_ownership.js",
"chars": 4480,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/bin/config.js",
"chars": 2448,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/bin/exports.js",
"chars": 3379,
"preview": "#! /usr/bin/env node\n/** ***********************************************************************************************"
},
{
"path": "source/bin/json.js",
"chars": 59017,
"preview": "#!/usr/bin/env node\n/**\n * Copyright (c) 2014 Trent Mick. All rights reserved.\n * Copyright (c) 2014 Joyent Inc. All rig"
},
{
"path": "source/bin/launch.js",
"chars": 10050,
"preview": "#! /usr/bin/env node\n/** ***********************************************************************************************"
},
{
"path": "source/bin/license.js",
"chars": 2533,
"preview": "#! /usr/bin/env node\n/** ***********************************************************************************************"
},
{
"path": "source/bin/license.txt",
"chars": 1440,
"preview": "/*********************************************************************************************************************\n "
},
{
"path": "source/bin/name.js",
"chars": 2604,
"preview": "#! /usr/bin/env node\n/** ***********************************************************************************************"
},
{
"path": "source/bin/update-public.sh",
"chars": 4180,
"preview": "#!/bin/bash\n\n# Stop immediately when any commands fail\n[ \"$DEBUG\" == 'true' ] && set -x\nset -e -o pipefail\n\nprint_usage("
},
{
"path": "source/bin/upload.sh",
"chars": 2837,
"preview": "#!/bin/bash\n\n# Stop immediately when any commands fail\n[ \"$DEBUG\" == 'true' ] && set -x\nset -e -o pipefail\n\nprint_usage("
},
{
"path": "source/bin/wait.js",
"chars": 2926,
"preview": "#! /usr/bin/env node\n/** ***********************************************************************************************"
},
{
"path": "source/cli/.coveragerc",
"chars": 137,
"preview": "[run]\nomit =\n tests/*\n ./run-pytest.py\nsource =\n aws_solutions/qnabot\n aws_solutions/core\n\n[lcov]\noutput = c"
},
{
"path": "source/cli/README.md",
"chars": 665,
"preview": "# QnABot CLI\nThe QnABot on AWS CLI supports the capability to import and export questions and answers from your QnABot s"
},
{
"path": "source/cli/aws_solutions/core/__init__.py",
"chars": 700,
"preview": "######################################################################################################################\n#"
},
{
"path": "source/cli/aws_solutions/core/config.py",
"chars": 2610,
"preview": "######################################################################################################################\n#"
},
{
"path": "source/cli/aws_solutions/core/helpers.py",
"chars": 2823,
"preview": "######################################################################################################################\n#"
},
{
"path": "source/cli/aws_solutions/core/logging.py",
"chars": 1871,
"preview": "######################################################################################################################\n#"
},
{
"path": "source/cli/aws_solutions/qnabot/cli/__init__.py",
"chars": 476,
"preview": "######################################################################################################################\n#"
},
{
"path": "source/cli/aws_solutions/qnabot/cli/qnabot_cli.py",
"chars": 5169,
"preview": "######################################################################################################################\n#"
},
{
"path": "source/cli/aws_solutions/qnabot/cli/qnabot_cli_helper.py",
"chars": 24699,
"preview": "######################################################################################################################\n#"
},
{
"path": "source/cli/pyproject.toml",
"chars": 493,
"preview": "[tool.poetry]\nname = \"cli\"\ndescription = \"Cli Module\"\npackage-mode = false\n\n[tool.poetry.dependencies]\npython = \"^3.10\"\n"
},
{
"path": "source/cli/pytest.ini",
"chars": 1357,
"preview": "[pytest]\ntestpaths = tests\nenv =\n MOTO_ACCOUNT_ID=111111111111\n SOLUTION_ID=SO9900test\n SOLUTION_VERSION=v0.0.1"
},
{
"path": "source/cli/run-pytest.py",
"chars": 552,
"preview": "#!/bin/bash\n############################################################################################################"
},
{
"path": "source/cli/tests/__init__.py",
"chars": 499,
"preview": "#!/usr/bin/env python3\n#################################################################################################"
},
{
"path": "source/cli/tests/aws_solutions/core/__init__.py",
"chars": 476,
"preview": "######################################################################################################################\n#"
},
{
"path": "source/cli/tests/aws_solutions/core/test_helpers.py",
"chars": 1839,
"preview": "######################################################################################################################\n#"
},
{
"path": "source/cli/tests/aws_solutions/core/test_logging.py",
"chars": 1704,
"preview": "######################################################################################################################\n#"
},
{
"path": "source/cli/tests/aws_solutions/core/test_solution_config.py",
"chars": 3947,
"preview": "######################################################################################################################\n#"
},
{
"path": "source/cli/tests/aws_solutions/qnabot/__init__.py",
"chars": 476,
"preview": "######################################################################################################################\n#"
},
{
"path": "source/cli/tests/aws_solutions/qnabot/fixtures/cloudformation_fixtures.py",
"chars": 1511,
"preview": "######################################################################################################################\n#"
},
{
"path": "source/cli/tests/aws_solutions/qnabot/fixtures/qnabot-test-template.yaml",
"chars": 1756,
"preview": "AWSTemplateFormatVersion: '2010-09-09'\n\nParameters:\n Param1:\n Description: Param1\n Type: String\n\nResources:\n "
},
{
"path": "source/cli/tests/aws_solutions/qnabot/fixtures/s3_fixtures.py",
"chars": 2635,
"preview": "######################################################################################################################\n#"
},
{
"path": "source/cli/tests/aws_solutions/qnabot/test_qnabot_cli.py",
"chars": 712,
"preview": "######################################################################################################################\n#"
},
{
"path": "source/cli/tests/aws_solutions/qnabot/test_qnabot_cli_helper.py",
"chars": 8659,
"preview": "######################################################################################################################\n#"
},
{
"path": "source/cli/tests/conftest.py",
"chars": 1053,
"preview": "#!/usr/bin/env python3\n#################################################################################################"
},
{
"path": "source/docs/Blogpost-BranchingNavigation.json",
"chars": 11788,
"preview": "{\n \"qna\": [\n {\n \"qid\": \"Previous\",\n \"a\": \"Unable to go to the previous stop...\",\n \"r\": {\n "
},
{
"path": "source/docs/Blogpost-SimpleNavigation.json",
"chars": 3315,
"preview": "{\n \"qna\": [\n {\n \"qid\": \"Previous\",\n \"a\": \"Unable to go to the previous room...\",\n \"r\": {\n \"ti"
},
{
"path": "source/docs/Blogpost-SimpleNavigationSupporting.json",
"chars": 6822,
"preview": "{\n \"qna\": [\n {\n \"qid\": \"Previous\",\n \"a\": \"Unable to go to the previous stop...\",\n \"r\": {\n \"ti"
},
{
"path": "source/docs/LLM_Retrieval_and_generative_question_answering/README.md",
"chars": 15042,
"preview": "# Large Language Model - Text Generation (Generative Question Answering) and Query Disambiguation for Conversational Ret"
},
{
"path": "source/docs/PII_Detection_And_Redaction/README.md",
"chars": 4074,
"preview": "# Personally Identifiable Information (PII) Redaction and Rejection in QnABot\n\nQnABot now offers PII handling capabiliti"
},
{
"path": "source/docs/Technical Information.md",
"chars": 14165,
"preview": "\n- [Resources](#resources)\n - [Cognito](#cognito)\n - [S3](#s3)\n - [Firehose](#firehose)\n - [APIGateway](#apigateway)"
},
{
"path": "source/docs/VPC_support/README.md",
"chars": 9202,
"preview": "# VPC Support\n\n(QnaBot on AWS version 6.0.0 - May 2024)\n\nThis feature allows deployment of QnABot components within VPC "
},
{
"path": "source/docs/architecture.xml",
"chars": 145761,
"preview": "<mxfile host=\"drawio.corp.amazon.com\" agent=\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, "
},
{
"path": "source/docs/bedrock_guardrails/README.md",
"chars": 9506,
"preview": "# Amazon Bedrock Guardrails Integration with QnABot on AWS\n\nQnABot on AWS implements a comprehensive guardrail system th"
},
{
"path": "source/docs/bedrock_knowledgebase_rag/README.md",
"chars": 7978,
"preview": "# Retrieval Augmentation Generation (RAG) using Amazon Bedrock Knowledge Base:\n\nBy integrating with the [Amazon Bedrock "
},
{
"path": "source/docs/bot_routing/README.md",
"chars": 5856,
"preview": "# Bot Routing - Preview Mode\n(version 1.3 - July 2024)\n\nBots exist to perform a variety of automation tasks. Usually the"
},
{
"path": "source/docs/client_filters.md",
"chars": 587,
"preview": "# Client Filters\n\nClient filtering allows you to set a parameter for each question stored in QnABot. The answer to a que"
},
{
"path": "source/docs/connect_callback/README.md",
"chars": 2367,
"preview": "# New Connect Callback Example\n\nNew example demonstrating how QnABot can be asked by a user for a live agent based phone"
},
{
"path": "source/docs/custom_domain_name_setup/README.md",
"chars": 5416,
"preview": "# Setup Custom Domain Name for QnABot Designer and Client\nThis readme provides information on how to setup a custom doma"
},
{
"path": "source/docs/custom_terminology_guide/README.md",
"chars": 1860,
"preview": "# Using Custom Terminologies with Amazon Translate\n\nQnABot now supports Amazon Translate's [custom terminology](https://"
},
{
"path": "source/docs/custom_terminology_guide/sample.csv",
"chars": 182,
"preview": "en,fr,de,es\ncustom terminology,custom terminology,custom terminology,custom terminology\n\n\n1 - create reusable layer for "
},
{
"path": "source/docs/excel_import/README.md",
"chars": 3489,
"preview": "# Excel Workbook Import\n\nQnABot supports importing questions and answers from Microsoft Excel (xlsx) workbooks.\n\nA [samp"
},
{
"path": "source/docs/handlebars/README.md",
"chars": 8252,
"preview": "# Handlebars\n\n## Simple example\n\nQnABot now lets you use [Handlebars](https://handlebarsjs.com/) templates in your answe"
},
{
"path": "source/docs/intent_slot_matching/README.md",
"chars": 10822,
"preview": "# Intent and Slot matching -- an early implementation\nQnABot supports different types of question and answer workflows. "
},
{
"path": "source/docs/kendra_crawler_guide/README.md",
"chars": 2124,
"preview": "# Amazon Kendra Web Crawler Integration\n\nPlease read the [Amazon Kendra Integration](../../workshops/kendra/README.md) f"
},
{
"path": "source/docs/kendra_fallback/README.md",
"chars": 5179,
"preview": "# Kendra Fallback Function\n\nThis feature searches a set of Kendra indexes as a fallback mechanism to provide answers whe"
},
{
"path": "source/docs/kendra_redirect/README.md",
"chars": 2802,
"preview": "# Kendra Redirect\nQnABot supports multiple mechanisms for dynamic interaction flows such as: \n- using Lambda Hooks in a "
},
{
"path": "source/docs/lambda_hooks/README.md",
"chars": 6670,
"preview": "# Extending QnABot with Lambda hook functions\n\nContent Designer gives you the ability to dynamically generate answers by"
},
{
"path": "source/docs/lambda_hooks/lambda_hook_sdk.MD",
"chars": 15203,
"preview": "# Methods\n\nThese are the available methods:\n\n- [get_step](#get_step)\n- [get_args](#get_args)\n- [get_lex_event](#get_lex_"
},
{
"path": "source/docs/lambda_hooks/q-business-lambda-hook-example/README.md",
"chars": 10273,
"preview": "# QnABot LambdaHook for Amazon Q Business (preview)\n\n| :zap: The QnAbot LambdaHook for Amazon Q Business has been"
},
{
"path": "source/docs/lambda_hooks/q-business-lambda-hook-example/q-business-lambda-hook-template.yml",
"chars": 8976,
"preview": "######################################################################################################################\n#"
},
{
"path": "source/docs/llm_streaming_responses/README.md",
"chars": 5293,
"preview": "# Streaming Responses from QnABot (7.0.0+)\n\nThe streaming responses feature enhances the responses from QnABot by retur"
},
{
"path": "source/docs/multilanguage_support/README.md",
"chars": 12310,
"preview": "# MultiLanguage Support\n\nQnABot supports both voice and text interactions in multiple languages. QnABot can detect the p"
},
{
"path": "source/docs/overview/README.md",
"chars": 4515,
"preview": "# Overview\n\nChatbots are a great way to make information available for your users. With QnABot you can deploy a chatbot "
},
{
"path": "source/docs/password_reset/README.md",
"chars": 1009,
"preview": "# Password Reset for Default Admin User\nThe default admin user that is deployed with QnABot is not automatically verifie"
},
{
"path": "source/docs/qnabot_cli/README.md",
"chars": 7767,
"preview": "# AWS QnABot Command Line Interface (CLI)\n\nThe AWS QnABot CLI supports the capability to `import` and `export` questions"
},
{
"path": "source/docs/recent_topics_lambda_hook_example/README.md",
"chars": 3998,
"preview": "# Create Recent Topics Response Walkthrough\n\nThe CreateRecentTopicsResponse Lambda hook demonstrates how you can extend "
},
{
"path": "source/docs/recent_topics_lambda_hook_example/recent topic settings.json",
"chars": 259,
"preview": "{\"topic::Comprehend\":\"Amazon Comprehend::Comprehend\",\"topic::Kendra\":\"Amazon Kendra::Kendra\",\"topic::Lex\":\"Amazon Lex::L"
},
{
"path": "source/docs/recent_topics_lambda_hook_example/recent_topics_settings.json",
"chars": 285,
"preview": "{\n \"topic::Comprehend\": \"Amazon Comprehend::Comprehend\",\n \"topic::Kendra\": \"Amazon Kendra::Kendra\",\n \"topic::Lex\": \"A"
},
{
"path": "source/docs/semantic_matching_using_LLM_embeddings/README.md",
"chars": 7878,
"preview": "# Semantic question matching, using Large Language Model Text Embeddings\n\nQnABot can now use text embeddings to provide "
},
{
"path": "source/docs/settings.md",
"chars": 18082,
"preview": "# QnABot Settings\n\n| Setting | Valid values | Description |\n|---------|--------------|--------------|\n| ENABLE_DEBUG_RES"
},
{
"path": "source/docs/tuning_accuracy_guide/README.md",
"chars": 15685,
"preview": "# Tuning Recognition Accuracy\n\n## Overview\n\nChatbots are a great way to make information available for your users.\nWith "
},
{
"path": "source/docs/update_or_migrate_deployment/README.md",
"chars": 12442,
"preview": "# In-place upgrade of QnABot\n\nIf you have previously deployed the solution and want to perform in-place upgrade, please "
},
{
"path": "source/docs/using_cloud9/README.md",
"chars": 5478,
"preview": "# Using AWS Cloud9 to Deploy QnABot\n\nQnABot can be installed via a properly configured [AWS Cloud 9](https://aws.amazon."
},
{
"path": "source/docs/zombie.json",
"chars": 515,
"preview": "{\n \"qna\": [\n {\n \"qid\": \"zombie.1\",\n \"q\": [\n \"What are Zombies\"\n "
},
{
"path": "source/eslint.config.js",
"chars": 2562,
"preview": "const js = require('@eslint/js');\nconst pluginVue = require('eslint-plugin-vue');\nconst pluginVuePug = require('eslint-p"
},
{
"path": "source/lambda/Makefile",
"chars": 184,
"preview": "LAMBDAS=$(shell for l in $$(ls . | grep -v test.js | grep -v README.md | grep -v Makefile);do echo ./$$l;done)\n\n.PHONY: "
},
{
"path": "source/lambda/README.md",
"chars": 139,
"preview": "# Lambda Functions\nThese are individual lambda function that are too big to fit into cloudformation template or require "
},
{
"path": "source/lambda/aws-sdk-layer/Makefile",
"chars": 384,
"preview": "NAME=$(shell basename $(shell pwd))\nDST=../../build/lambda/$(NAME).zip\n\nRESOURCES := $(shell find . | grep -v node_modu"
},
{
"path": "source/lambda/aws-sdk-layer/package.json",
"chars": 676,
"preview": "{\n \"name\": \"aws-layer\",\n \"version\": \"7.3.8\",\n \"description\": \"QnABot Lambda aws-sdk-layer\",\n \"main\": \"index."
},
{
"path": "source/lambda/aws-sdk-layer/sdk-config/customSdkConfig.js",
"chars": 752,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/Makefile",
"chars": 265,
"preview": "NAME=$(shell basename $(shell pwd))\nDST=../../build/lambda/$(NAME).zip\nRESOURCES := $(shell find . | grep -v node_modul"
},
{
"path": "source/lambda/cfn/README.md",
"chars": 279,
"preview": "# CFN Lambda\nThis Lambda is responsible for create the customer resources in the CloudFormation templates. /lib contains"
},
{
"path": "source/lambda/cfn/index.js",
"chars": 4117,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/jest.config.js",
"chars": 808,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/lib/ApiDeployment.js",
"chars": 3543,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/lib/CognitoDomain.js",
"chars": 1995,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/lib/CognitoLogin.js",
"chars": 2950,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/lib/CognitoRole.js",
"chars": 2459,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/lib/CognitoUrl.js",
"chars": 1152,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/lib/DefaultSettings.json",
"chars": 17594,
"preview": "{\n \"ENABLE_DEBUG_RESPONSES\": {\n \"SettingCategory\": \"ChatBotTesting\",\n \"DefaultValue\": \"false\"\n },\n "
},
{
"path": "source/lambda/cfn/lib/ESCognitoClient.js",
"chars": 1816,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/lib/LambdaVersion.js",
"chars": 1227,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/lib/ModelAccess.js",
"chars": 9517,
"preview": "/** ************************************************************************************************\n * Copyright Amaz"
},
{
"path": "source/lambda/cfn/lib/OpenSearchUpdates.js",
"chars": 1684,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/lib/PostUpgradeImport.js",
"chars": 4830,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/lib/PreUpgradeExport.js",
"chars": 4098,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/lib/S3Lambda.js",
"chars": 1749,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/lib/S3Unzip.js",
"chars": 2682,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/lib/S3Version.js",
"chars": 1436,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/lib/SettingsInitializer.js",
"chars": 13465,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/lib/Variable.js",
"chars": 1267,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/lib/base.js",
"chars": 665,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/lib/lex.js",
"chars": 23243,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/lib/util/customSdkConfig.js",
"chars": 734,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
},
{
"path": "source/lambda/cfn/lib/util/parseIntFromLexRequestObject.js",
"chars": 1417,
"preview": "/** ************************************************************************************************\n* Copyright Amazo"
}
]
// ... and 877 more files (download for full content)
About this extraction
This page contains the full source code of the aws-samples/aws-ai-qna-bot GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1077 files (8.5 MB), approximately 2.3M tokens, and a symbol index with 1487 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.