From f96de263e7499f60e9df367d00f048d8653570c1 Mon Sep 17 00:00:00 2001
From: GaliM-W <89501387+GaliM-W@users.noreply.github.com>
Date: Sun, 22 Oct 2023 16:28:16 +1300
Subject: [PATCH 01/11] Change quotes on end of module page
---
.../ethicai-spa/src/components/interactive/quiz/QuizStart.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/project/ethicai-spa/src/components/interactive/quiz/QuizStart.vue b/project/ethicai-spa/src/components/interactive/quiz/QuizStart.vue
index 4c94519..7d6a4ee 100644
--- a/project/ethicai-spa/src/components/interactive/quiz/QuizStart.vue
+++ b/project/ethicai-spa/src/components/interactive/quiz/QuizStart.vue
@@ -9,7 +9,7 @@ export default {
QUIZ
-
You have completed "{{ module_name }}". Take this quick
+
You have completed “{{ module_name }}”. Take this quick
quiz to check your understanding.
From 041cfce8284ad6226a43241f039adb54940fbfa0 Mon Sep 17 00:00:00 2001
From: Kevin Wong
Date: Sun, 22 Oct 2023 16:01:35 +1300
Subject: [PATCH 03/11] upload createMarkovChain lambda function
---
.../aws-lambda-functions/createMarkovChain.py | 106 ++++++++++++++++++
1 file changed, 106 insertions(+)
create mode 100644 project/aws-lambda-functions/createMarkovChain.py
diff --git a/project/aws-lambda-functions/createMarkovChain.py b/project/aws-lambda-functions/createMarkovChain.py
new file mode 100644
index 0000000..e09da85
--- /dev/null
+++ b/project/aws-lambda-functions/createMarkovChain.py
@@ -0,0 +1,106 @@
+import json
+import random
+import boto3
+import os
+
+from collections import defaultdict
+
+# Cached Markov chains
+markov_chains = {}
+
+
+def create_markov_chain(words, context_size=2):
+ markov_chain = defaultdict(list)
+ context_so_far = []
+
+ for word in words:
+ if len(context_so_far) == context_size:
+ markov_chain[tuple(context_so_far)].append(word)
+ context_so_far.pop(0)
+ # the "#" symbols aren't included in the dict key
+ context_so_far.append(word.strip("#").strip())
+
+ return markov_chain
+
+
+def tokenise(string):
+ # add 'ꙮ' after every space
+ string = string.replace(" ", " ꙮ")
+ # add 'ꙮ' after every newline
+ string = string.replace("\n", "\nꙮ")
+ # split on 'ꙮ'
+ split = string.split("ꙮ")
+ return [token for token in split if token != ""]
+
+
+def generate(corpus, user_input, context_size, words_to_generate):
+ words = tokenise(corpus)
+ markov_chain = markov_chains.get((context_size, corpus))
+
+ if markov_chain is None:
+ markov_chain = create_markov_chain(words, context_size)
+ markov_chains[(context_size, corpus)] = markov_chain
+
+ generated_words = []
+ tagged_indices = []
+
+ start = tokenise(user_input)[-context_size:]
+
+ # if user input not long enough
+ if len(start) < context_size:
+ # pick random key that starts with the user input
+ possible_starts = [
+ key
+ for key in markov_chain.keys()
+ if key[len(key) - len(start) :] == tuple(start)
+ ]
+ # and use that instead
+ start = random.choice(possible_starts)
+
+ current_key = tuple(start)
+
+ for _ in range(words_to_generate):
+ next_words = markov_chain.get(current_key, [])
+ if not next_words:
+ break
+
+ next_word = random.choice(next_words)
+ generated_words.append(next_word)
+ current_key = tuple(list(current_key[1:]) + [next_word.strip("#").strip()])
+
+ if next_word.startswith("#"):
+ tagged_indices.append(len(generated_words) - 1)
+
+ generated_words = [word.strip("#").replace("\n", " ") for word in generated_words]
+
+ return "".join(generated_words), tagged_indices
+
+
+def lambda_handler(event, context):
+ s3 = boto3.resource("s3")
+ bucket_name = os.environ["BUCKET_NAME"]
+ input_body = json.loads(event["body"])
+ directory = "alt-corpora/" + input_body["corpus"]
+ context_size = input_body["context_size"]
+ words_to_generate = input_body["words_to_generate"]
+ corpus = ""
+
+ for obj in s3.Bucket(bucket_name).objects.filter(Prefix=directory):
+ body = obj.get()["Body"].read().decode("utf-8")
+ corpus += body
+
+ user_input = input_body["input"]
+ generated, biased_indices = generate(
+ corpus, user_input, context_size, words_to_generate
+ )
+
+ return {
+ "statusCode": 200,
+ "body": json.dumps(
+ {
+ "input": user_input,
+ "generated": generated,
+ "biased_indices": biased_indices,
+ }
+ ),
+ }
From 2674270e07ea5f8da4185cf12ddea9dd7a212331 Mon Sep 17 00:00:00 2001
From: Kevin Wong
Date: Sun, 22 Oct 2023 16:01:40 +1300
Subject: [PATCH 04/11] upload getImagePairs lambda function
---
.../aws-lambda-functions/getImagePairs.mjs | 68 +++++++++++++++++++
1 file changed, 68 insertions(+)
create mode 100644 project/aws-lambda-functions/getImagePairs.mjs
diff --git a/project/aws-lambda-functions/getImagePairs.mjs b/project/aws-lambda-functions/getImagePairs.mjs
new file mode 100644
index 0000000..a8d8ddd
--- /dev/null
+++ b/project/aws-lambda-functions/getImagePairs.mjs
@@ -0,0 +1,68 @@
+import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
+import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
+
+const BUCKET_NAME = process.env.BUCKET_NAME;
+const NUM_FILES = parseInt(process.env.NUM_FILES);
+const PRESIGNED_URL_EXPIRATION = 1800;
+const JSON_FILE_KEY = "ai-painting-demo/image_pair_txt.json";
+
+const client = new S3Client();
+
+async function generatePresignedUrl(key) {
+ const command = new GetObjectCommand({
+ Bucket: BUCKET_NAME,
+ Key: key,
+ });
+
+ const presignedUrl = await getSignedUrl(client, command, {
+ expiresIn: PRESIGNED_URL_EXPIRATION,
+ });
+
+ return presignedUrl;
+}
+
+async function getImagePair(id) {
+ const realImagePath = `ai-painting-demo/real/${id}.jpg`;
+ const fakeImagePath = `ai-painting-demo/fake/${id}.jpg`;
+
+ const realImageURL = await generatePresignedUrl(realImagePath);
+ const fakeImageURL = await generatePresignedUrl(fakeImagePath);
+
+ return { realImageURL, fakeImageURL };
+}
+
+function getRandomInts(quantity, max) {
+ const set = new Set()
+ while (set.size < quantity) {
+ set.add(Math.floor(Math.random() * max) + 1)
+ }
+ return set
+}
+
+async function getStringArrayFromJSON() {
+ const command = new GetObjectCommand({
+ Bucket: BUCKET_NAME,
+ Key: JSON_FILE_KEY,
+ });
+
+ const response = await client.send(command);
+ const jsonData = await response.Body.transformToString('utf-8');
+ return JSON.parse(jsonData);
+}
+
+export const handler = async (event, context) => {
+ const { numImages } = JSON.parse(event.body);
+
+ const imageIDs = Array.from(getRandomInts(numImages, NUM_FILES));
+ const imagePairs = await Promise.all(imageIDs.map(id => getImagePair(id)));
+ const stringArray = await getStringArrayFromJSON();
+
+ const realImageURLs = imagePairs.map(pair => pair.realImageURL);
+ const fakeImageURLs = imagePairs.map(pair => pair.fakeImageURL);
+ const imageStrings = imageIDs.map(id => stringArray[id - 1]);
+
+ return ({
+ statusCode: 200,
+ body: JSON.stringify({ realImageURLs, fakeImageURLs, imageStrings })
+ });
+};
From af630c3402cd574a268225bc7914a2a2ed37c8d0 Mon Sep 17 00:00:00 2001
From: Kevin Wong
Date: Sun, 22 Oct 2023 16:01:45 +1300
Subject: [PATCH 05/11] upload promptGPT lambda function
---
project/aws-lambda-functions/promptGPT.py | 48 +++++++++++++++++++++++
1 file changed, 48 insertions(+)
create mode 100644 project/aws-lambda-functions/promptGPT.py
diff --git a/project/aws-lambda-functions/promptGPT.py b/project/aws-lambda-functions/promptGPT.py
new file mode 100644
index 0000000..f2bb5fb
--- /dev/null
+++ b/project/aws-lambda-functions/promptGPT.py
@@ -0,0 +1,48 @@
+import json
+import boto3
+from hugchat import hugchat
+from hugchat.login import Login
+
+client = boto3.client("secretsmanager")
+
+
+def init_chatbot(email, passwd):
+ sign = Login(email, passwd)
+ cookies = sign.login()
+ chatbot = hugchat.ChatBot(cookies=cookies.get_dict())
+
+ # Switch model (default: meta-llama/Llama-2-70b-chat-hf. )
+ # chatbot.switch_llm(1) # Switch to `meta-llama/Llama-2-70b-chat-hf`
+ chatbot.switch_llm(0) # Switch to `OpenAssistant/oasst-sft-6-llama-30b-xor`
+ return chatbot
+
+
+def get_secret():
+ secret_name = "hugchat-credentials"
+ region_name = "ap-southeast-2"
+
+ session = boto3.session.Session()
+ client = session.client(service_name="secretsmanager", region_name=region_name)
+
+ try:
+ get_secret_value_response = client.get_secret_value(SecretId=secret_name)
+ except ClientError as e:
+ raise e
+
+ secret = get_secret_value_response["SecretString"]
+ return secret
+
+
+def lambda_handler(event, context):
+ creds = json.loads(get_secret())
+ email = creds["hugchat_email"]
+ passwd = creds["hugchat_passwd"]
+
+ input_body = json.loads(event["body"])
+ prompt = input_body["prompt"]
+ print("User prompt: " + prompt)
+
+ chatbot = init_chatbot(email, passwd)
+ query_response = chatbot.query(prompt, retry_count=2)
+ print("Response: " + query_response)
+ return {"statusCode": 200, "body": json.dumps({'response': query_response.text})}
From d80397d5b3085d7c050bf386fd102c8968e8927d Mon Sep 17 00:00:00 2001
From: Kevin Wong
Date: Sun, 22 Oct 2023 16:05:23 +1300
Subject: [PATCH 06/11] updated readme.md
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index bafa49d..8bb1201 100644
--- a/README.md
+++ b/README.md
@@ -69,13 +69,13 @@ cd project/ethicai-spa
npm install
```
-To run the project locally, run the following command in the terminal:
+To run the project locally, run the following command in the terminal (in the `project/ethicai-spa` directory):
```bash
npm run serve
```
-To build the project, run the following command in the terminal:
+To build the project, run the following command in the terminal (in the `project/ethicai-spa` directory):
```bash
npm run build
From 184400b2d61de2cc16d4e7da761fe304ffbf865d Mon Sep 17 00:00:00 2001
From: Kevin Wong
Date: Sun, 22 Oct 2023 16:10:28 +1300
Subject: [PATCH 07/11] updated readme.md to include aws lambda functions
---
README.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/README.md b/README.md
index 8bb1201..7dcff56 100644
--- a/README.md
+++ b/README.md
@@ -81,6 +81,9 @@ To build the project, run the following command in the terminal (in the `project
npm run build
```
+The AWS Lambda functions used in the project are located in the `project/aws-lambda-functions` directory. They are actively deployed on AWS Lambda and are not required to run the project locally.
+These functions cannot be run locally due to the nature of AWS Lambda (needs the appropriate security roles, permissions, etc.), as well as environmental variables that are not defined in the project.
+
### Usage Examples 🔍
***
From e12aeb5115eeea9b02be9d9ebd09beb2614c040e Mon Sep 17 00:00:00 2001
From: Kevin Wong
Date: Sun, 22 Oct 2023 16:12:27 +1300
Subject: [PATCH 08/11] tweaked readme.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 7dcff56..8bc8c00 100644
--- a/README.md
+++ b/README.md
@@ -81,7 +81,7 @@ To build the project, run the following command in the terminal (in the `project
npm run build
```
-The AWS Lambda functions used in the project are located in the `project/aws-lambda-functions` directory. They are actively deployed on AWS Lambda and are not required to run the project locally.
+The AWS Lambda functions used in the project are located in the `project/aws-lambda-functions` directory. They are actively deployed on AWS Lambda and are not required to run the project locally.\
These functions cannot be run locally due to the nature of AWS Lambda (needs the appropriate security roles, permissions, etc.), as well as environmental variables that are not defined in the project.
### Usage Examples 🔍
From 606ceecb41e4fc6c64414892033257703f312cd5 Mon Sep 17 00:00:00 2001
From: Kevin Wong
Date: Sun, 22 Oct 2023 16:14:07 +1300
Subject: [PATCH 09/11] updated readme.md again
---
README.md | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 8bc8c00..ce67624 100644
--- a/README.md
+++ b/README.md
@@ -81,7 +81,9 @@ To build the project, run the following command in the terminal (in the `project
npm run build
```
-The AWS Lambda functions used in the project are located in the `project/aws-lambda-functions` directory. They are actively deployed on AWS Lambda and are not required to run the project locally.\
+\
+The AWS Lambda functions used in the project are located in the `project/aws-lambda-functions` directory. They are actively deployed on AWS Lambda and are not required to run the project locally.
+
These functions cannot be run locally due to the nature of AWS Lambda (needs the appropriate security roles, permissions, etc.), as well as environmental variables that are not defined in the project.
### Usage Examples 🔍
From eec926f70c696e07f1bf821d159f5cde26a59316 Mon Sep 17 00:00:00 2001
From: Kevin Wong
Date: Sun, 22 Oct 2023 23:15:36 +1300
Subject: [PATCH 10/11] fixed jira word styling
---
README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index ce67624..5fab881 100644
--- a/README.md
+++ b/README.md
@@ -20,10 +20,10 @@ We are a passionate team of final-year computer science students with diverse sk
### Project Management Tool 🛠️ ###
***
-Our team used [JIRA](https://ethicai.atlassian.net/jira/software/projects/EAI/boards/1/timeline?shared=&atlOrigin=eyJpIjoiMmMxMDViYmQ4MGUxNGRlNjgwZjgzNGRiOGIyM2VlNmQiLCJwIjoiaiJ9) and [Trello](https://trello.com/b/Ydes48Ob/cs399) as our primary project management tool. For all other project-related files, such as API specifications and meeting notes, we used [Google Drive](https://drive.google.com).
+Our team used [Jira](https://ethicai.atlassian.net/jira/software/projects/EAI/boards/1/timeline?shared=&atlOrigin=eyJpIjoiMmMxMDViYmQ4MGUxNGRlNjgwZjgzNGRiOGIyM2VlNmQiLCJwIjoiaiJ9) and [Trello](https://trello.com/b/Ydes48Ob/cs399) as our primary project management tool. For all other project-related files, such as API specifications and meeting notes, we used [Google Drive](https://drive.google.com).
-Our JIRA Gantt Chart/Timeline is shown below:
-![JIRA Project Timeline](./markdown/jira-timeline.png)
+Our Jira Gantt Chart/Timeline is shown below:
+![Jira Project Timeline](./markdown/jira-timeline.png)
### Technologies 👨💻
From 44a6a3a0574e740ad45dc4a4ba96260bc3731e8a Mon Sep 17 00:00:00 2001
From: Kevin Wong
Date: Sun, 22 Oct 2023 23:16:54 +1300
Subject: [PATCH 11/11] updated trello link in readme.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 5fab881..0cf7ddf 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ We are a passionate team of final-year computer science students with diverse sk
### Project Management Tool 🛠️ ###
***
-Our team used [Jira](https://ethicai.atlassian.net/jira/software/projects/EAI/boards/1/timeline?shared=&atlOrigin=eyJpIjoiMmMxMDViYmQ4MGUxNGRlNjgwZjgzNGRiOGIyM2VlNmQiLCJwIjoiaiJ9) and [Trello](https://trello.com/b/Ydes48Ob/cs399) as our primary project management tool. For all other project-related files, such as API specifications and meeting notes, we used [Google Drive](https://drive.google.com).
+Our team used [Jira](https://ethicai.atlassian.net/jira/software/projects/EAI/boards/1/timeline?shared=&atlOrigin=eyJpIjoiMmMxMDViYmQ4MGUxNGRlNjgwZjgzNGRiOGIyM2VlNmQiLCJwIjoiaiJ9) and [Trello](https://trello.com/b/Ydes48Ob/ethicai) as our primary project management tool. For all other project-related files, such as API specifications and meeting notes, we used [Google Drive](https://drive.google.com).
Our Jira Gantt Chart/Timeline is shown below:
![Jira Project Timeline](./markdown/jira-timeline.png)