Skip to content

Commit

Permalink
Merge branch 'develop' v0.1.14
Browse files Browse the repository at this point in the history
  • Loading branch information
rstrahan committed Dec 22, 2023
2 parents 8fa4739 + 04a68fe commit cc5285a
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 5 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.1.14] - 2023-12-22
### Added
- Amazon Q Business Expert plugin now suports optional file attachments via Lex Web UI (v0.20.4) attach option and the new userFileUpload session attribute - PR #23.


## [0.1.13] - 2023-12-06
### Added
- Bedrock plugin updates to support new text models - #22
Expand Down Expand Up @@ -75,7 +80,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Initial release

[Unreleased]: https://github.com/aws-samples/qnabot-on-aws-plugin-samples/compare/v0.1.13...develop
[Unreleased]: https://github.com/aws-samples/qnabot-on-aws-plugin-samples/compare/v0.1.14...develop
[0.1.14]: https://github.com/aws-samples/qnabot-on-aws-plugin-samples/releases/tag/v0.1.13
[0.1.13]: https://github.com/aws-samples/qnabot-on-aws-plugin-samples/releases/tag/v0.1.13
[0.1.12]: https://github.com/aws-samples/qnabot-on-aws-plugin-samples/releases/tag/v0.1.12
[0.1.11]: https://github.com/aws-samples/qnabot-on-aws-plugin-samples/releases/tag/v0.1.11
Expand Down
Binary file added images/FileAttach.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions lambdas/qna_bot_qbusiness_lambdahook/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Amazon Q is a new generative AI-powered application that helps users get work do

In this repo we share a project which lets you use Amazon Q's generative AI to enable QnABot users to access your organization's data and knowledge sources via conversational question-answering. You can connect to your organization data via data source connectors and integrate it with the QnABot LambdaHook plugin for Amazon Q to enable access to your QnABot users. It allows your users to converse with Amazon Q using QnABot to ask questions and get answers based on company data, get help creating new content such as emails, and performing tasks.

NEW! This plugin now supports attachments! Use the newest version of the [Lex Web UI](http://amazon.com/chatbotui) - version 0.20.4 or later - to add local file attachments to your conversation. There's more information on this feature in the Lex Web UI [File Upload README](https://github.com/aws-samples/aws-lex-web-ui/blob/master/README-file-upload.md).

It's pretty cool. It's easy to deploy in your own AWS Account, and add to your own QnABot. We show you how below.

![Amazon Q Demo](../../images/AmazonQLambdaHook.png)
Expand Down Expand Up @@ -59,3 +61,12 @@ Alternatively, you can supply an explicit `"Prompt"` key in the `QnAItemLambdaHo
4. Say *Hello*. And start asking questions!
5. Enjoy.

### Using file attachments

This plugin now supports attachments! Use the newest version of the [Lex Web UI](http://amazon.com/chatbotui) - version 0.20.4 or later - to add local file attachments to your conversation. There's more information on this feature in the Lex Web UI [File Upload README](https://github.com/aws-samples/aws-lex-web-ui/blob/master/README-file-upload.md).
When deploying or updating your Lex Web UI, you can reuse QnABot's existing **ImportBucket** name as the **UploadBucket** parameter - it already has a CORS policy that will work, and the Q Business plugin lambda role already grants read access to uploads in this bucket. To find your QnaBot's ImportBucket, use the `Resources` tab in the QnABot stack to search for the bucket reasorce with the logical name **ImportBucket**.

Here's an example of what you can do with attachments - it is a beautiful thing!

![Amazon Q Demo](../../images/FileAttach.png)

31 changes: 28 additions & 3 deletions lambdas/qna_bot_qbusiness_lambdahook/src/lambdahook.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
endpoint_url=AMAZONQ_ENDPOINT_URL
)

def get_amazonq_response(prompt, context, amazonq_userid):
def get_amazonq_response(prompt, context, amazonq_userid, attachments):
print(f"get_amazonq_response: prompt={prompt}, app_id={AMAZONQ_APP_ID}, context={context}")
input = {
"applicationId": AMAZONQ_APP_ID,
Expand All @@ -31,8 +31,11 @@ def get_amazonq_response(prompt, context, amazonq_userid):
input["parentMessageId"] = context["parentMessageId"]
else:
input["clientToken"] = str(uuid.uuid4())

if attachments:
input["attachments"] = attachments

print("Amazon Q Input: ", json.dumps(input))
print("Amazon Q Input: ", input)
try:
resp = qbusiness_client.chat_sync(**input)
except Exception as e:
Expand Down Expand Up @@ -76,6 +79,27 @@ def get_args_from_lambdahook_args(event):
print("..continuing")
return parameters

def getS3File(s3Path):
if s3Path.startswith("s3://"):
s3Path = s3Path[5:]
s3 = boto3.resource('s3')
bucket, key = s3Path.split("/", 1)
obj = s3.Object(bucket, key)
return obj.get()['Body'].read()

def getAttachments(event):
userFilesUploaded = event["req"]["session"].get("userFilesUploaded",[])
attachments = []
for userFile in userFilesUploaded:
print(f"getAttachments: userFile={userFile}")
attachments.append({
"data": getS3File(userFile["s3Path"]),
"name": userFile["fileName"]
})
# delete userFilesUploaded from session
event["res"]["session"].pop("userFilesUploaded",None)
return attachments

def format_response(event, amazonq_response):
# get settings, if any, from lambda hook args
# e.g: {"Prefix":"<custom prefix heading>", "ShowContext": False}
Expand Down Expand Up @@ -142,12 +166,13 @@ def lambda_handler(event, context):
userInput = args.get("Prompt", event["req"]["question"])
qnabotcontext = event["req"]["session"].get("qnabotcontext",{})
amazonq_context = qnabotcontext.get("amazonq_context",{})
attachments = getAttachments(event)
amazonq_userid = os.environ.get("AMAZONQ_USER_ID")
if not amazonq_userid:
amazonq_userid = get_user_email(event)
else:
print(f"using configured default user id: {amazonq_userid}")
amazonq_response = get_amazonq_response(userInput, amazonq_context, amazonq_userid)
amazonq_response = get_amazonq_response(userInput, amazonq_context, amazonq_userid, attachments)
event = format_response(event, amazonq_response)
print("Returning response: %s" % json.dumps(event))
return event
10 changes: 9 additions & 1 deletion lambdas/qna_bot_qbusiness_lambdahook/template.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
AWSTemplateFormatVersion: "2010-09-09"
Description: >
Amazon Q (Business) Lambda Hook function for using with 'QnABot on AWS'.
Use with the 'no_hits' (CustomNoMatches) item to use Amazon Q when no good answers are found by other methods - v0.1.12
Use with the 'no_hits' (CustomNoMatches) item to use Amazon Q when no good answers are found by other methods - v0.1.14
Parameters:

Expand Down Expand Up @@ -56,6 +56,14 @@ Resources:
- "qbusiness:ChatSync"
Resource: !Sub "arn:aws:qbusiness:${AWS::Region}:${AWS::AccountId}:application/${AmazonQAppId}"
PolicyName: QBusinessPolicy
- PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- "s3:GetObject"
Resource: "arn:aws:s3:::*-importbucket-*/*"
PolicyName: S3ImportBucketPolicy

QnaItemLambdaHookFunction:
Type: AWS::Lambda::Function
Expand Down

0 comments on commit cc5285a

Please sign in to comment.