Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
caco3 committed Jan 18, 2025
1 parent c634977 commit c917a06
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 75 deletions.
33 changes: 30 additions & 3 deletions discussion-bot/readme.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,39 @@
# Discussion Bot
To parse a discussion and generate a response, acall it with
The discussion bot can be used to create auto-responses on discussions.
The `responses.md` file is used a sa database and contains responses and trigger words.
When `response_generator.py` gets fed with a text, it parses the text, finds matching trigger words in the database and creates a list of suggestions.
The suggestions, wrapped between the content of `response_intro.md` and `response_outro.md`, then get put together to a response.

## Usage
To parse a discussion and generate a response, call it with
```bash
python response_generator.py --actor <ACTOR> --title <TITLE> --body <BODY>
```

Example:
```bash
python response_generator.py --actor "CaCO3" --title "Test" --body "--body "Hi all. I have always wrong value and reflections. Also home assistant does not get any data."
python response_generator.py --actor "CaCO3" --title "Test" --body "Hi all. I have always wrong value and reflections. Also home assistant does not get any data."
```

## Data Format
It is important to make sure that the `responses.md` file has the right format!
Altrough it is a markdown file and can be rendered by a markdown viewer, it actually is parsed by the script.
Thus the format must be as following:
- A response starts with a title line and must have a leading `#` followed by a whitespace.
- The title can be empty. It also can be used to note some comments.
- The title line is followed by a one-line response. All markdown keywords are allowed, but it must stay on one line.
- Then one or more trigger words get listed as a list. Each line has one trigger word ar phrase.
- It is suggested to separate the responses with empty lines for easier visual separation, although this is optional.

Example:
```
# Wrong Transitions
Check parameter numberanalogtodigittransitionstart
- lagging
- late transition
- early transition
```
# Testing


## Testing
See [test/readme.md](test/readme.md)
35 changes: 0 additions & 35 deletions discussion-bot/response_data.txt

This file was deleted.

69 changes: 35 additions & 34 deletions discussion-bot/response_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,47 @@
class Data_Record_Parser():
data_records = []

def __init__(self, data_file):
records_count = 0
record_started = False
with open(data_file, "r") as f:
def __init__(self, response_file):
self.parse_responses(response_file)

def parse_responses(self, response_file):
with open(response_file, "r") as f:
for line in f:
line = line.strip()
if line.startswith(";"): # Comment line
if line == "": # Empty line
continue

if line != "": # Line contains data
if not record_started:
record_started = True
self.data_records.append({"response": None, "trigger_patterns": []})
records_count += 1

if self.data_records[records_count - 1]["response"] == None: # Record has no response yet -> Add line as response
self.data_records[records_count - 1]["response"] = line
else: # Record has a response -> Add line as trigger pattern
self.data_records[records_count - 1]["trigger_patterns"].append(line)
else: # Empty line -> end of record
record_started = False
continue
if line.startswith("#"): # Title line -> response start
if len(self.data_records) > 1: # This is not the first response
# Make sure the previous response record has at least one trigger pattern
if len(self.data_records[-2]["trigger_patterns"]) == 0: # Number of trigger patterns of the 2nd last record
raise Exception("The previous response record has no trigger patterns!")

self.data_records.append({"title": line.replace("# ", ""), "response": None, "trigger_patterns": []})

elif line.startswith("-"): # Trigger pattern line
if self.data_records[-1]["response"] == None: # Record has no response yet
raise Exception("The response record has no response line!")
self.data_records[-1]["trigger_patterns"].append(line.replace("- ", "")) # Add to trigger patterns

else: # Response line
self.data_records[-1]["response"] = line # Add as response line

log.info(f"Found {len(self.data_records)} data records")
# import pprint
# pprint.pprint(self.data_records, width=300)

log.info(f"Found {records_count} data records")

def get_records(self):
return self.data_records


class Response_Generator():
def __init__(self, data_file):
parser = Data_Record_Parser(data_file)
def __init__(self, response_file, intro_file, outro_file):
parser = Data_Record_Parser(response_file)
self.data_records = parser.get_records()
self.intro = open(intro_file, "r").read()
self.outro = open(outro_file, "r").read()

def process_discussion(self, actor, title, body):
"""Analyses the given title and body and creates a response based on the found trigger words
Expand All @@ -55,22 +63,13 @@ def process_discussion(self, actor, title, body):
break

if len(responses) > 0: # At least one trigger pattern matched
response = f"Hi @{actor}"
response += """
I am the (experimental) AIOTED-Bot 🤖
Have you already checked our [documentation](https://jomjol.github.io/AI-on-the-edge-device-docs)?
I analyzed your question and I might be able to help you. Here are some useful links based on your input:
"""
response = self.intro + "\n"
response = response.replace("{actor}", "{" + actor + "}")

for finding in responses:
response += f" - **{finding[0]}:** {finding[1]}\n"

response += """
If this all does not help and you need support of an experienced user or developer to look into it (after you really studied the documentation), you can write a reply with the text `help-needed`.
Please be aware that we are a small team and run this project in our private, free time, so our time to give support is really limitted!"""
response += "\n" +self.outro
else:
response = ""

Expand All @@ -92,7 +91,9 @@ def process_discussion(self, actor, title, body):
title = args.title
body = args.body

rg = Response_Generator(os.path.dirname(__file__) + "/" + "response_data.txt")
rg = Response_Generator(os.path.dirname(__file__) + "/" + "responses.md",
os.path.dirname(__file__) + "/" + "response_intro.md",
os.path.dirname(__file__) + "/" + "response_outro.md")

response = rg.process_discussion(actor, title, body)

Expand Down
6 changes: 6 additions & 0 deletions discussion-bot/response_intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Hi @{actor}

I am the (experimental) [AIOTED](https://jomjol.github.io/AI-on-the-edge-device-docs/FAQs/#what-does-aioted-mean)-Bot 🤖

Have you already checked our [documentation](https://jomjol.github.io/AI-on-the-edge-device-docs)?
I analyzed your question and I might be able to help you. Here are some useful links based on your input:
2 changes: 2 additions & 0 deletions discussion-bot/response_outro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
If this all does not help and you need support of an experienced user or developer to look into it (after you really studied the documentation), you can write a reply with the text `help-needed`.
Please be aware that we are a small team and run this project in our private and free time, so our time to give support is really limited!
33 changes: 33 additions & 0 deletions discussion-bot/responses.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Rate too high
See the [Rate too high in our FAQ](https://jomjol.github.io/AI-on-the-edge-device-docs/FAQs/#rate-too-high-read)
- Rate too high

# Homeassistant
Check HomeAssistant
- homeassistant
- Home Assistant
- Home-assistant

# Wrong Values
Improve ROI, ...
- wrong values

# Wrong Transitions
Check parameter numberanalogtodigittransitionstart
- lagging
- late transition
- early transition
- transition

# Reflections
Improve LED, diffusor, see xxx
- reflection

# LCD, Dot Display, Matrix
See LCD/Matrix xxx
LCD, matrix

# shifted
Make sure to set []() correctly.
- shift
- decimal place
4 changes: 3 additions & 1 deletion discussion-bot/test/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ pip install -r requirements.txt
```

## Test Data
The `discussions.json` file contains a list of discussion threads (first comment only).
The `discussions.json.tar.gz` file contains a list of discussion threads (first comment only).
The list got generated with the following cmd:
```bash
for i in {1..10}; do wget "https://api.github.com/repos/jomjol/AI-on-the-edge-device/discussions?per_page=100&page=$i" -O discussions_$i.json; done
```

Afterward I removed the first and last line of each file (remove the `[` and `]`) merged the files and wrap the new one again with `[` and `]`.

The `discussions.json.tar.gz` file gets extracted to `discussions.json` if it does not exist yet.

## Run Tests
If you run the `test.py` script it will generate a HTML page which shows all discussions and the matching responses.
9 changes: 7 additions & 2 deletions discussion-bot/test/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@
output_file.write("<th class=vertical-separator>Response</th>")
output_file.write("</tr>")

rg = Response_Generator(os.path.dirname(__file__) + "/../" + "response_data.txt")
rg = Response_Generator(os.path.dirname(__file__) + "/../" + "responses.md",
os.path.dirname(__file__) + "/../" + "response_intro.md",
os.path.dirname(__file__) + "/../" + "response_outro.md")

for i in range(len(discussions) - 1, -1, -1):
log.info(f"Processing discussion {len(discussions) - i}/{len(discussions)}...")
Expand Down Expand Up @@ -94,8 +96,11 @@

output_file.write(f"<tr><td><h3>{title_html}</h3>{body_html}</td><td class=vertical-separator>{response_html}</td></tr>")

# break # testing

output_file.write("</table>")
output_file.write("</body>")
output_file.write("</html>")
output_file.close()

log.info("Done. Check the result.html file.")
log.info("Done. Please open the result.html file in a webbrowser.")

0 comments on commit c917a06

Please sign in to comment.