Spaces:
Sleeping
Sleeping
Commit
·
0fadcb9
1
Parent(s):
7b864ba
first E2E working implementation
Browse files- test.json +0 -61
- .gitignore +0 -1
- app.py +36 -69
- form/__init__.py +0 -0
- form/form.pdf +0 -0
- schema.py → form/form.py +54 -51
- llm/__init__.py +0 -0
- llm/llm.py +11 -0
- prompts/__init__.py +0 -0
- prompts/prompts_manager.py +19 -0
- prompts/questions.txt +13 -0
- system_prompt.txt → prompts/system_prompt.txt +0 -0
- prompts/verification_prompt2.txt +13 -0
- questions.txt +0 -10
- repository/ollama.py +12 -11
- utils/__init__.py +0 -0
- utils/date_utils.py +3 -0
- utils/parsing_utils.py +17 -0
- verification_prompt.txt +0 -27
test.json
DELETED
@@ -1,61 +0,0 @@
|
|
1 |
-
[
|
2 |
-
{
|
3 |
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
4 |
-
"$id": "https://www.enricorampazzo.tech/dam_helper.schema.json",
|
5 |
-
"title": "Answer",
|
6 |
-
"description": "an answer to a question",
|
7 |
-
"type": "array",
|
8 |
-
"items": {
|
9 |
-
"type": "object",
|
10 |
-
"properties": {
|
11 |
-
"question": {
|
12 |
-
"type": "string"
|
13 |
-
},
|
14 |
-
"answer": {
|
15 |
-
"type": ["string", "null"]
|
16 |
-
}
|
17 |
-
},
|
18 |
-
"required": ["question", "answer"]
|
19 |
-
}
|
20 |
-
},
|
21 |
-
{
|
22 |
-
"question": "1) What do you need to do?",
|
23 |
-
"answer": "Pest control"
|
24 |
-
},
|
25 |
-
{
|
26 |
-
"question": "2) In which community is the work taking place?",
|
27 |
-
"answer": "JBR"
|
28 |
-
},
|
29 |
-
{
|
30 |
-
"question": "3) In which building?",
|
31 |
-
"answer": "Sadaf 5"
|
32 |
-
},
|
33 |
-
{
|
34 |
-
"question": "4) In which unit/apartment number?",
|
35 |
-
"answer": "2408"
|
36 |
-
},
|
37 |
-
{
|
38 |
-
"question": "5) Am I an owner or a tenant?",
|
39 |
-
"answer": "unclear"
|
40 |
-
},
|
41 |
-
{
|
42 |
-
"question": "6) In which date is the work taking place?",
|
43 |
-
"answer": "7/9/2024"
|
44 |
-
},
|
45 |
-
{
|
46 |
-
"question": "7) In which date will the work finish?",
|
47 |
-
"answer": null
|
48 |
-
},
|
49 |
-
{
|
50 |
-
"question": "8) What is my contact number?",
|
51 |
-
"answer": null
|
52 |
-
},
|
53 |
-
{
|
54 |
-
"question": "9) What is the name of the contracting company?",
|
55 |
-
"answer": "Breathe Maintenance"
|
56 |
-
},
|
57 |
-
{
|
58 |
-
"question": "10) What is the contact number of the contracting company?",
|
59 |
-
"answer": null
|
60 |
-
}
|
61 |
-
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.gitignore
CHANGED
@@ -1,4 +1,3 @@
|
|
1 |
.idea
|
2 |
-
form.pdf
|
3 |
/.idea/
|
4 |
/.idea/inspectionProfiles/
|
|
|
1 |
.idea
|
|
|
2 |
/.idea/
|
3 |
/.idea/inspectionProfiles/
|
app.py
CHANGED
@@ -1,78 +1,45 @@
|
|
1 |
-
import
|
2 |
-
import re
|
3 |
-
from json import JSONDecodeError
|
4 |
|
|
|
5 |
from repository.ollama import OllamaRepository
|
6 |
-
from
|
|
|
7 |
|
8 |
-
# this regex is most definitely *not* going to make my system blow up unexpectedly at some point in the future
|
9 |
-
get_questions_and_answers_regex = re.compile(r'{\s*"question":\s*"([^"]+)",\s*"answer":\s*(\s*null\s*|"[^"]+"\s*)}')
|
10 |
|
|
|
|
|
11 |
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
""")
|
18 |
|
19 |
|
20 |
if __name__ == '__main__':
|
21 |
-
|
22 |
-
questions = questions_file.read()
|
23 |
-
with open("system_prompt.txt") as system_prompt_file:
|
24 |
-
system_prompt = system_prompt_file.read()
|
25 |
-
with open("verification_prompt.txt") as verification_prompt_file:
|
26 |
-
verification_prompt = verification_prompt_file.read()
|
27 |
-
verification_prompt = verification_prompt.replace("{questions}", questions)
|
28 |
user_prompt = input(f"Please describe what you need to do. To get the best results "
|
29 |
-
|
30 |
-
|
31 |
-
ollama_repository = OllamaRepository("llama3.1",
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
ollama_repository.send_prompt(f"When parsing this json {answers} I got this error {str(e)}. "
|
54 |
-
f"Fix this error and return just the corrected json without adding anything else"))
|
55 |
-
|
56 |
-
print("trying to parse the corrected json")
|
57 |
-
try:
|
58 |
-
json_answers = json.loads(answer["content"])
|
59 |
-
corrected_json_was_ok+=1
|
60 |
-
print_current_status(successful, successful_at_first_attempt, corrected_json_was_ok,
|
61 |
-
regex_got_all_answers)
|
62 |
-
except JSONDecodeError as e:
|
63 |
-
print("still error, going old school")
|
64 |
-
regex_parse_result = {}
|
65 |
-
for match in get_questions_and_answers_regex.findall(answer["content"]):
|
66 |
-
question, answer = match
|
67 |
-
regex_parse_result[question] = answer
|
68 |
-
if len(regex_parse_result) == 10:
|
69 |
-
print("I got all 10 answers apparently")
|
70 |
-
successful+=1
|
71 |
-
regex_got_all_answers+=1
|
72 |
-
print_current_status(successful, successful_at_first_attempt, corrected_json_was_ok,
|
73 |
-
regex_got_all_answers)
|
74 |
-
else:
|
75 |
-
print(f"unable to parse \n {answers}\n giving up")
|
76 |
-
break
|
77 |
-
|
78 |
-
|
|
|
1 |
+
from pathlib import Path
|
|
|
|
|
2 |
|
3 |
+
from prompts.prompts_manager import PromptsManager
|
4 |
from repository.ollama import OllamaRepository
|
5 |
+
from llm.llm import ModelRoles, Model
|
6 |
+
from form.form import work_categories, build_form_data_from_answers, write_pdf_form
|
7 |
|
|
|
|
|
8 |
|
9 |
+
def check_for_missing_answers(parsed_questions: dict[int, str]):
|
10 |
+
return [k for k in parsed_questions if parsed_questions[k] is None]
|
11 |
|
12 |
+
|
13 |
+
def ask_again(missing_questions: list[int], user_questions: list[str], parsed_questions: dict[int, str]):
|
14 |
+
for id_ in missing_questions:
|
15 |
+
answer = input(f"I could not find the answer to this question: {user_questions[id_].lower()}")
|
16 |
+
parsed_questions[id_] = answer
|
|
|
17 |
|
18 |
|
19 |
if __name__ == '__main__':
|
20 |
+
prompts_manager = PromptsManager()
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
user_prompt = input(f"Please describe what you need to do. To get the best results "
|
22 |
+
f"try to answer all the following questions:\n{'\n'.join(prompts_manager.questions)}\n\n>")
|
23 |
+
|
24 |
+
ollama_repository = OllamaRepository(Model("llama3.1",
|
25 |
+
ModelRoles("system", "user", "assistant")),
|
26 |
+
prompts_manager.system_prompt,
|
27 |
+
)
|
28 |
+
ollama_repository.send_prompt(f"Ingest the following information: {user_prompt}")
|
29 |
+
answers = {}
|
30 |
+
for idx, q in enumerate(prompts_manager.verification_prompt):
|
31 |
+
answer = ollama_repository.send_prompt(
|
32 |
+
f"Answer the following question, if the answer is not present just answer null. Keep the answer brief: {q}")
|
33 |
+
answers[idx] = None if 'null' in answer["content"].lower() else answer['content']
|
34 |
+
missing_answers = check_for_missing_answers(answers)
|
35 |
+
while missing_answers:
|
36 |
+
ask_again(missing_answers, prompts_manager.questions, answers)
|
37 |
+
missing_answers = check_for_missing_answers(answers)
|
38 |
+
answer = ollama_repository.send_prompt(
|
39 |
+
f"The work to do is {answers[1]}. Given the following categories {work_categories.values()} which ones are the most relevant? Only return one categories, separated by a semicolon")
|
40 |
+
categories = []
|
41 |
+
for category in answer["content"].split(";"):
|
42 |
+
categories.extend([k for k, v in work_categories.items() if category in v])
|
43 |
+
|
44 |
+
form_data = build_form_data_from_answers(answers, categories, f"{Path(__file__, "..", "signature.png")}")
|
45 |
+
write_pdf_form(form_data, Path("signed_form1.pdf"))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
form/__init__.py
ADDED
File without changes
|
form/form.pdf
ADDED
Binary file (697 kB). View file
|
|
schema.py → form/form.py
RENAMED
@@ -1,5 +1,40 @@
|
|
|
|
1 |
from typing import TypedDict
|
|
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
|
4 |
class FormFields(TypedDict, total=True):
|
5 |
start_date: str
|
@@ -44,55 +79,6 @@ class FormFields(TypedDict, total=True):
|
|
44 |
minor_work: str
|
45 |
|
46 |
|
47 |
-
class MinorWorkForm:
|
48 |
-
def __init__(self):
|
49 |
-
self.start_date: str
|
50 |
-
self.end_date: str
|
51 |
-
self.signed_by: str
|
52 |
-
self.signature_date: str
|
53 |
-
self.community: str
|
54 |
-
self.email: str
|
55 |
-
self.unit_no: str
|
56 |
-
self.contact_number: str
|
57 |
-
self.building_name: str
|
58 |
-
self.contractor_name: str
|
59 |
-
self.contractor_email: str
|
60 |
-
self.contractor_contact_number: str
|
61 |
-
self.occupant_name: str
|
62 |
-
self.civil: bool
|
63 |
-
self.electrical_AC: bool
|
64 |
-
self.furniture_delivery: bool
|
65 |
-
self.handyman: bool
|
66 |
-
self.pest_control: bool
|
67 |
-
self.sail_shade: bool
|
68 |
-
self.wardrobes: bool
|
69 |
-
self.wooden_flooring: bool
|
70 |
-
self.plumbing_sanitary: bool
|
71 |
-
self.safety_systems: bool
|
72 |
-
self.soft_landscaping: bool
|
73 |
-
self.balcony_tiles: bool
|
74 |
-
self.bathroom_toilet_refurbish: bool
|
75 |
-
self.staircase_railing: bool
|
76 |
-
self.storage_box: bool
|
77 |
-
self.tiling_works: bool
|
78 |
-
self.doors_door_frames: bool
|
79 |
-
self.gypsum_ceiling: bool
|
80 |
-
self.kitchen_refurbish: bool
|
81 |
-
self.lights_and_sockets: bool
|
82 |
-
self.painting_wallpapering: bool
|
83 |
-
self.seating_area_barbecuing_fountain: bool
|
84 |
-
self.other_work_checkbox: bool
|
85 |
-
self.owner: bool
|
86 |
-
self.tenant: bool
|
87 |
-
self.signature: str
|
88 |
-
|
89 |
-
class ModelRoles:
|
90 |
-
def __init__(self, system_role, user_role, ai_role):
|
91 |
-
self.system_role = system_role
|
92 |
-
self.user_role = user_role
|
93 |
-
self.ai_role = ai_role
|
94 |
-
|
95 |
-
|
96 |
form_fields_map: FormFields = {"start_date": "From", "end_date": "to", "signed_by": "name-10",
|
97 |
"signature_date": "From--1", "community": "Name-2", "email": "Name-3",
|
98 |
"unit_no": "Name-4", "contact_number": "Name-5", "building_name": "Name-6",
|
@@ -101,11 +87,28 @@ form_fields_map: FormFields = {"start_date": "From", "end_date": "to", "signed_b
|
|
101 |
"other_work": "name-19", "civil": "3", "electrical_AC": "10", "furniture_delivery": "14",
|
102 |
"handyman": "18", "pest_control": "21", "sail_shade": "12", "wardrobes": "16",
|
103 |
"wooden_flooring": "24",
|
104 |
-
"plumbing_sanitary": "4", "
|
105 |
"balcony_tiles": "13", "bathroom_toilet_refurbish": "20",
|
106 |
"staircase_railing": "17", "storage_box": "11", "tiling_works": "15",
|
107 |
"doors_door_frames": "6", "gypsum_ceiling": "22", "kitchen_refurbish": "7",
|
108 |
"lights_and_sockets": "23", "painting_wallpapering": "19",
|
109 |
"seating_area_barbecuing_fountain": "8",
|
110 |
"other_work_checkbox": "69", "owner": "Check Box4", "tenant": "Check Box3",
|
111 |
-
"signature": "Signature2", "minor_work": "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pathlib import Path
|
2 |
from typing import TypedDict
|
3 |
+
from PyPDFForm import PdfWrapper
|
4 |
|
5 |
+
from utils.date_utils import get_today_date_as_dd_mm_yyyy
|
6 |
+
from utils.parsing_utils import find_and_parse_date, find_and_parse_phone_number
|
7 |
+
|
8 |
+
|
9 |
+
def build_form_data_from_answers(answers: dict[int, str], categories: list[str], signature: str | None = None):
|
10 |
+
form_data = {}
|
11 |
+
for category in categories:
|
12 |
+
form_data[form_fields_map[category]] = True
|
13 |
+
form_data[form_fields_map["minor_work"]] = True
|
14 |
+
form_data[form_fields_map["signed_by"]] = answers[0]
|
15 |
+
form_data[form_fields_map["community"]] = answers[2]
|
16 |
+
form_data[form_fields_map["building_name"]] = answers[3]
|
17 |
+
form_data[form_fields_map["unit_no"]] = answers[4]
|
18 |
+
form_data[form_fields_map["owner" if "owner" in answers[5].lower() else "tenant"]] = True
|
19 |
+
form_data[form_fields_map["start_date"]] = find_and_parse_date(answers[6])
|
20 |
+
form_data[form_fields_map["end_date"]] = find_and_parse_date(answers[7])
|
21 |
+
form_data[form_fields_map["contact_number"]] = find_and_parse_phone_number(answers[8])
|
22 |
+
form_data[form_fields_map["contractor_name"]] = answers[9]
|
23 |
+
form_data[form_fields_map["contractor_contact_number"]] = answers[10]
|
24 |
+
form_data[form_fields_map["contractor_email"]] = answers[11]
|
25 |
+
form_data[form_fields_map["email"]] = answers[12]
|
26 |
+
form_data[form_fields_map["occupant_name"]] = answers[0]
|
27 |
+
form_data[form_fields_map["signature_date"]] = get_today_date_as_dd_mm_yyyy()
|
28 |
+
if signature:
|
29 |
+
form_data[form_fields_map["signature"]] = signature
|
30 |
+
return form_data
|
31 |
+
|
32 |
+
def write_pdf_form(form_data: dict[str, str | bool | int], output_path:Path):
|
33 |
+
base_form_path = Path(__file__, "..", "form.pdf")
|
34 |
+
with open(base_form_path, "rb") as blank_form:
|
35 |
+
filled_form = PdfWrapper(blank_form).fill(form_data)
|
36 |
+
with open(output_path, "wb+") as filled_form_file:
|
37 |
+
filled_form_file.write(filled_form.read())
|
38 |
|
39 |
class FormFields(TypedDict, total=True):
|
40 |
start_date: str
|
|
|
79 |
minor_work: str
|
80 |
|
81 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
form_fields_map: FormFields = {"start_date": "From", "end_date": "to", "signed_by": "name-10",
|
83 |
"signature_date": "From--1", "community": "Name-2", "email": "Name-3",
|
84 |
"unit_no": "Name-4", "contact_number": "Name-5", "building_name": "Name-6",
|
|
|
87 |
"other_work": "name-19", "civil": "3", "electrical_AC": "10", "furniture_delivery": "14",
|
88 |
"handyman": "18", "pest_control": "21", "sail_shade": "12", "wardrobes": "16",
|
89 |
"wooden_flooring": "24",
|
90 |
+
"plumbing_sanitary": "4", "safety_systems": "4", "soft_landscaping": "9",
|
91 |
"balcony_tiles": "13", "bathroom_toilet_refurbish": "20",
|
92 |
"staircase_railing": "17", "storage_box": "11", "tiling_works": "15",
|
93 |
"doors_door_frames": "6", "gypsum_ceiling": "22", "kitchen_refurbish": "7",
|
94 |
"lights_and_sockets": "23", "painting_wallpapering": "19",
|
95 |
"seating_area_barbecuing_fountain": "8",
|
96 |
"other_work_checkbox": "69", "owner": "Check Box4", "tenant": "Check Box3",
|
97 |
+
"signature": "Signature2", "minor_work": "2"}
|
98 |
+
work_categories = {"other_work": "other work", "civil": "Civil work, masonry",
|
99 |
+
"electrical_AC": "electrical / AC / air conditioning", "furniture_delivery": "furniture delivery",
|
100 |
+
"handyman": "handyman work, repairs, furniture assembly, furniture installation", "pest_control": "pest control",
|
101 |
+
"sail_shade": "sail shade, curtains", "wardrobes": "wardrobes",
|
102 |
+
"wooden_flooring": "wooden flooring",
|
103 |
+
"plumbing_sanitary": "plumbing / sanitary / bathroom works such as repairing a sink, tap, toilet, shower or bathtub",
|
104 |
+
"safety_systems": "safety systems, surveillance systems installation",
|
105 |
+
"soft_landscaping": "soft landscaping", "balcony_tiles": "installation and fixing of balcony tiles",
|
106 |
+
"bathroom_toilet_refurbish": "bathroom or toilet refurbishment or renovation",
|
107 |
+
"staircase_railing": "staircase rails, handrails", "storage_box": "storage box",
|
108 |
+
"tiling_works": "tiles installation or repair",
|
109 |
+
"doors_door_frames": "work related to doors and door frames",
|
110 |
+
"gypsum_ceiling": "gypsum ceiling installation or maintenance",
|
111 |
+
"kitchen_refurbish": "kitchen renovation or refurbishment",
|
112 |
+
"lights_and_sockets": "installation of lights, ceiling lights, power sockets",
|
113 |
+
"painting_wallpapering": "painting, wallpaper installation",
|
114 |
+
"seating_area_barbecuing_fountain": "installation or renovation of outdoor structures such as seating area, barbecuing area or fountains"}
|
llm/__init__.py
ADDED
File without changes
|
llm/llm.py
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
class ModelRoles:
|
2 |
+
def __init__(self, system_role: str, user_role: str, ai_role: str):
|
3 |
+
self.system_role: str = system_role
|
4 |
+
self.user_role: str = user_role
|
5 |
+
self.ai_role: str = ai_role
|
6 |
+
|
7 |
+
|
8 |
+
class Model:
|
9 |
+
def __init__(self, name: str, roles: ModelRoles):
|
10 |
+
self.name: str = name
|
11 |
+
self.roles: ModelRoles = roles
|
prompts/__init__.py
ADDED
File without changes
|
prompts/prompts_manager.py
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import datetime
|
2 |
+
from pathlib import Path
|
3 |
+
|
4 |
+
from utils.date_utils import get_today_date_as_dd_mm_yyyy
|
5 |
+
|
6 |
+
|
7 |
+
class PromptsManager:
|
8 |
+
def __init__(self):
|
9 |
+
base_path = Path(__file__, "..")
|
10 |
+
with open(Path(base_path, "system_prompt.txt")) as sysprompt_file:
|
11 |
+
self.system_prompt: str = sysprompt_file.read()
|
12 |
+
with open(Path(base_path, "questions.txt")) as questions_file:
|
13 |
+
self.questions: list[str] = questions_file.readlines()
|
14 |
+
with open(Path(base_path, "verification_prompt2.txt")) as verification_prompt_file:
|
15 |
+
verification_prompt = verification_prompt_file.readlines()
|
16 |
+
todays_date = get_today_date_as_dd_mm_yyyy()
|
17 |
+
for line in verification_prompt:
|
18 |
+
line.replace("{today}", todays_date)
|
19 |
+
self.verification_prompt: list[str] = verification_prompt
|
prompts/questions.txt
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
What is your full name?
|
2 |
+
What is the nature of the work you need to do?
|
3 |
+
In which community is the work taking place?
|
4 |
+
In which building?
|
5 |
+
In which unit/apartment number?
|
6 |
+
Are you an owner or a tenant?
|
7 |
+
In which date is the work taking place?
|
8 |
+
In which date will the work finish?
|
9 |
+
What is your contact number?
|
10 |
+
What is the name of the contracting company?
|
11 |
+
What is the contact number of the contracting company?
|
12 |
+
What is the email of the contracting company?
|
13 |
+
What is your email?
|
system_prompt.txt → prompts/system_prompt.txt
RENAMED
File without changes
|
prompts/verification_prompt2.txt
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
What is my full name?
|
2 |
+
What is the nature of the work I need to do?
|
3 |
+
In which community is the work taking place?
|
4 |
+
In which building?
|
5 |
+
In which unit/apartment number?
|
6 |
+
Am I the owner or the tenant?
|
7 |
+
In which date is the work taking place? Please answer with just a date formatted as dd/mm/yyyy. In case I used expressions like today, tomorrow, in two days, ecc, know that today it is 08/09/2024
|
8 |
+
In which date will the work finish? Please answer with just a date formatted as dd/mm/yyyy. In case I used expressions like today, tomorrow, in two days, ecc, know that today it is {today}. If no date is provided, consider that it will finish on the same day as the start date
|
9 |
+
What is my contact number?
|
10 |
+
What is the name of the contracting company?
|
11 |
+
What is the contact number of the contracting company?
|
12 |
+
What is the email of the contracting company?
|
13 |
+
What is your email?
|
questions.txt
DELETED
@@ -1,10 +0,0 @@
|
|
1 |
-
1) What do you need to do?
|
2 |
-
2) In which community is the work taking place?
|
3 |
-
3) In which building?
|
4 |
-
4) In which unit/apartment number?
|
5 |
-
5) Am I an owner or a tenant?
|
6 |
-
6) In which date is the work taking place?
|
7 |
-
7) In which date will the work finish?
|
8 |
-
8) What is my contact number?
|
9 |
-
9) What is the name of the contracting company?
|
10 |
-
10) What is the contact number of the contracting company?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
repository/ollama.py
CHANGED
@@ -1,21 +1,22 @@
|
|
1 |
import ollama
|
2 |
from ollama import Options
|
3 |
|
4 |
-
from
|
5 |
|
6 |
|
7 |
class OllamaRepository:
|
8 |
-
def __init__(self, model, system_msg
|
9 |
-
self.model = model
|
10 |
-
self.system_msg = system_msg
|
11 |
-
self.
|
12 |
-
self.message_history: list[dict[str, str]] = [{"role": self.roles.system_role, "content": system_msg}]
|
13 |
|
14 |
-
def send_prompt(self, prompt:str, add_to_history:bool =
|
15 |
-
options: Options = Options(temperature=0
|
16 |
-
self.message_history.append({"role": self.roles.user_role, "content":prompt})
|
17 |
-
response = ollama.chat(self.model, self.message_history, options=options)
|
18 |
-
answer = {"role": self.roles.ai_role, "content": response["message"]["content"]}
|
19 |
if add_to_history:
|
20 |
self.message_history.append(answer)
|
|
|
|
|
21 |
return answer
|
|
|
1 |
import ollama
|
2 |
from ollama import Options
|
3 |
|
4 |
+
from llm.llm import ModelRoles, Model
|
5 |
|
6 |
|
7 |
class OllamaRepository:
|
8 |
+
def __init__(self, model:Model, system_msg):
|
9 |
+
self.model: Model = model
|
10 |
+
self.system_msg: str = system_msg
|
11 |
+
self.message_history: list[dict[str, str]] = [{"role": self.model.roles.system_role, "content": system_msg}]
|
|
|
12 |
|
13 |
+
def send_prompt(self, prompt:str, add_to_history:bool = True) -> dict[str, str]:
|
14 |
+
options: Options = Options(temperature=0)
|
15 |
+
self.message_history.append({"role": self.model.roles.user_role, "content":prompt})
|
16 |
+
response = ollama.chat(self.model.name, self.message_history, options=options)
|
17 |
+
answer = {"role": self.model.roles.ai_role, "content": response["message"]["content"]}
|
18 |
if add_to_history:
|
19 |
self.message_history.append(answer)
|
20 |
+
else:
|
21 |
+
self.message_history.pop()
|
22 |
return answer
|
utils/__init__.py
ADDED
File without changes
|
utils/date_utils.py
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
import datetime
|
2 |
+
def get_today_date_as_dd_mm_yyyy():
|
3 |
+
return datetime.datetime.now().strftime("%d/%m/%Y")
|
utils/parsing_utils.py
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import re
|
2 |
+
parse_date_regex = re.compile(r"([0-9]{1,2}/[0-9]{1,2}/[0-9]{4})")
|
3 |
+
parse_phone_number_regex = re.compile(r"\+?[0-9]*")
|
4 |
+
|
5 |
+
|
6 |
+
def _find_and_parse(llm_answer, regex):
|
7 |
+
match = regex.findall(llm_answer)
|
8 |
+
return next(iter(match), None) if match else None
|
9 |
+
|
10 |
+
|
11 |
+
def find_and_parse_date(llm_answer: str) -> str | None:
|
12 |
+
return _find_and_parse(llm_answer, parse_date_regex)
|
13 |
+
|
14 |
+
|
15 |
+
def find_and_parse_phone_number(llm_answer: str):
|
16 |
+
return _find_and_parse(llm_answer, parse_phone_number_regex)
|
17 |
+
|
verification_prompt.txt
DELETED
@@ -1,27 +0,0 @@
|
|
1 |
-
Please tell if I answered the following questions:
|
2 |
-
|
3 |
-
{questions}
|
4 |
-
|
5 |
-
The answer should be a list of json objects that follow this schema and be legal json.
|
6 |
-
{
|
7 |
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
8 |
-
"$id": "https://www.enricorampazzo.tech/dam_helper.schema.json",
|
9 |
-
"title": "Answer",
|
10 |
-
"description": "an answer to a question",
|
11 |
-
"type": "object",
|
12 |
-
"properties": {
|
13 |
-
"question": {
|
14 |
-
"description": "the question being answered",
|
15 |
-
"type": "string"
|
16 |
-
},
|
17 |
-
"answer": {
|
18 |
-
"description": "the answer to the question",
|
19 |
-
"type": "string"
|
20 |
-
|
21 |
-
}
|
22 |
-
}
|
23 |
-
}
|
24 |
-
if the answer is a date format it as day/month/year.
|
25 |
-
If the answer contains temporal references such as 'tomorrow', 'in two days' etc. consider that today it is the
|
26 |
-
6th of september 2024.
|
27 |
-
If the answer is not provided just the answer string should be null
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|