drakosfire commited on
Commit
27c79bc
·
0 Parent(s):

Initial commit

Browse files
__pycache__/app.cpython-310.pyc ADDED
Binary file (2.01 kB). View file
 
__pycache__/store_helper.cpython-310.pyc ADDED
Binary file (5.79 kB). View file
 
__pycache__/utilities.cpython-310.pyc ADDED
Binary file (3.18 kB). View file
 
app.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # this imports the code from files and modules
2
+ import gradio as gr
3
+ import utilities as u
4
+ import os
5
+ import ctypes
6
+ import store_helper as sh
7
+
8
+
9
+ # This is a fix for the way that python doesn't release system memory back to the OS and it was leading to locking up the system
10
+ libc = ctypes.cdll.LoadLibrary("libc.so.6")
11
+ M_MMAP_THRESHOLD = -3
12
+
13
+ # Set malloc mmap threshold.
14
+ libc.mallopt(M_MMAP_THRESHOLD, 2**20)
15
+
16
+ # Declare accessible directories
17
+ base_dir = os.path.dirname(os.path.abspath(__file__)) # Gets the directory where the script is located
18
+ print(f"Base Directory :",base_dir)
19
+ list_of_static_dir = [os.path.join(base_dir, "output"),
20
+ os.path.join(base_dir, "dependencies"),
21
+ os.path.join(base_dir, "galleries")]
22
+ gr.set_static_paths(paths=list_of_static_dir)
23
+
24
+ # Build gradio app
25
+ # Storing everything inside the Blocks to be accessible to the app
26
+
27
+ with gr.Blocks() as demo:
28
+ # Functions and State Variables
29
+ store_description= gr.State()
30
+ specialties_description = gr.State()
31
+
32
+ def gen_store_desc(user_description):
33
+
34
+ llm_output = sh.call_llm_and_cleanup(user_description)
35
+ #user_monster = sh.convert_to_dict(llm_output)
36
+ #user_monster = llm_output
37
+ #keys_list = list(user_monster)
38
+
39
+
40
+ #Return each State variable twice, once to the variable and once to the textbox
41
+ return [llm_output,llm_output]
42
+
43
+ def gen_store_specialties(store_description):
44
+
45
+ llm_output = sh.call_llm_and_cleanup(store_description, specialties=True)
46
+ #user_monster = sh.convert_to_dict(llm_output)
47
+ #user_monster = llm_output
48
+ #keys_list = list(user_monster)
49
+
50
+
51
+ #Return each State variable twice, once to the variable and once to the textbox
52
+ return [llm_output,llm_output]
53
+
54
+ #Function to dynamically render textbox if it has text.
55
+ def update_visibility(textbox):
56
+ if not textbox:
57
+ return gr.update(visible=False)
58
+ return gr.update(visible=True)
59
+ with gr.Tab("Store"):
60
+ user_store_description = gr.Textbox(label = "Step 1 : What are the core qualities of the store?",
61
+ lines = 1, placeholder=f"Ex : A trade shop with a female ogre merchant, basic trade goods and travel supplies, has a secret basement for smuggling.",
62
+ elem_id= "custom-textbox")
63
+ desc_gen = gr.Button(value = "Click to Generate Description")
64
+ store_description_output = gr.Textbox(label = 'Description', lines = 2, interactive=True, visible=True)
65
+ store_description_output.change(fn=update_visibility,
66
+ inputs=[store_description_output],
67
+ outputs=[store_description_output])
68
+ desc_gen.click(fn = gen_store_desc, inputs = [user_store_description],
69
+ outputs= [store_description, store_description_output
70
+ ])
71
+
72
+ image_path_list= u.absolute_path("./folder_with_images")
73
+
74
+ with gr.Tab("Inventory"):
75
+ user_store_description = gr.Textbox(label = "Step 1 : What are the core qualities of the store?",
76
+ lines = 1, placeholder=f"Ex : A trade shop with a female ogre merchant, basic trade goods and travel supplies, has a secret basement for smuggling.",
77
+ elem_id= "custom-textbox")
78
+ desc_gen = gr.Button(value = "Click to Generate Description")
79
+ store_description_output = gr.Textbox(label = 'Description', lines = 2, interactive=True, visible=True)
80
+ store_description_output.change(fn=update_visibility,
81
+ inputs=[store_description_output],
82
+ outputs=[store_description_output])
83
+ desc_gen.click(fn = gen_store_desc, inputs = [user_store_description],
84
+ outputs= [store_description, store_description_output
85
+ ])
86
+
87
+ image_path_list= u.absolute_path("./folder_with_images")
88
+ if __name__ == "__main__":
89
+ demo.launch(allowed_paths=list_of_static_dir)
90
+
example_templates.py ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "store_name": "Gearwork Guises",
3
+ "location": {
4
+ "town": "Cogsworth",
5
+ "district": "Clocktower Quarter",
6
+ "street": "17 Steamvent Avenue"
7
+ },
8
+ "type": "Costume and Masquerade Shop",
9
+ "size": "Medium",
10
+ "description": "A whimsical two-story shop with brass fittings, gears adorning the walls, and steam-powered mannequins displaying the latest in steampunk fashion and imaginative costumes.",
11
+ "atmosphere": "Lively and eccentric, with the hiss of steam and ticking of clocks creating a constant ambient soundtrack. The air is perfumed with a mix of leather, oil, and exotic fabrics.",
12
+ "owners": [
13
+ {
14
+ "name": "Millicent Cogsworth",
15
+ "race": "Gnome",
16
+ "class": "Artificer",
17
+ "description": "A diminutive woman with wild copper hair and brass-rimmed spectacles, always wearing an outfit adorned with tiny, functional gears.",
18
+ "personality": "Excitable, creative, and prone to rambling about her latest inventions",
19
+ "secrets": ["She's developing a costume that can turn the wearer invisible", "She's a member of a secret society of innovative artificers"]
20
+ }
21
+ ],
22
+ "employees": [
23
+ {
24
+ "name": "Thaddeus Sprocket",
25
+ "role": "Tailor and Seamster",
26
+ "race": "Human",
27
+ "description": "Tall and lanky with a meticulously waxed mustache and a penchant for pin-striped vests",
28
+ "personality": "Precise, patient, and passionate about perfect fits"
29
+ },
30
+ {
31
+ "name": "Zephyr",
32
+ "role": "Apprentice and Shop Assistant",
33
+ "race": "Air Genasi",
34
+ "description": "An ethereal figure with hair that seems to float on unseen currents, wearing flowing garments with clockwork accents",
35
+ "personality": "Dreamy, absent-minded, but surprisingly insightful about customer preferences"
36
+ }
37
+ ],
38
+ "inventory": {
39
+ "costumes": [
40
+ {
41
+ "name": "Clockwork Corsair",
42
+ "type": "Full Costume",
43
+ "rarity": "Uncommon",
44
+ "value": "150 gold",
45
+ "properties": ["Adjustable fit", "Functional pocket watch"],
46
+ "weight": "8 lbs",
47
+ "description": "A swashbuckler's outfit with brass gears, a tricorn hat with goggles, and a clockwork parrot that sits on the shoulder",
48
+ "quote": "Ahoy, me hearties! Time waits for no pirate!",
49
+ "quantity": 3,
50
+ "condition": "Excellent"
51
+ }
52
+ ],
53
+ "masks": [
54
+ {
55
+ "name": "Gear Golem Visage",
56
+ "type": "Mask",
57
+ "rarity": "Rare",
58
+ "value": "75 gold",
59
+ "properties": ["Adjustable size", "Voice modulation"],
60
+ "weight": "2 lbs",
61
+ "description": "A brass mask with movable gears and glowing crystal eyes, changes the wearer's voice to a deep, resonant tone",
62
+ "quote": "Behind every mask is a story waiting to be told.",
63
+ "quantity": 5,
64
+ "condition": "New"
65
+ }
66
+ ],
67
+ "accessories": [
68
+ {
69
+ "name": "Pneumatic Propeller Pack",
70
+ "type": "Costume Accessory",
71
+ "rarity": "Very Rare",
72
+ "value": "300 gold",
73
+ "properties": ["Decorative", "Minor levitation (1 minute per day)"],
74
+ "weight": "10 lbs",
75
+ "description": "A backpack with extendable brass wings and a small steam engine, allows brief periods of flight",
76
+ "quote": "Why walk when you can soar?",
77
+ "quantity": 1,
78
+ "condition": "Pristine"
79
+ }
80
+ ]
81
+ },
82
+ "services": [
83
+ {
84
+ "name": "Custom Costume Creation",
85
+ "description": "Design and creation of unique costumes tailored to client specifications",
86
+ "price": "Starting at 200 gold"
87
+ },
88
+ {
89
+ "name": "Costume Repair and Modification",
90
+ "description": "Fixing damaged costumes or altering existing ones to fit new requirements",
91
+ "price": "50 gold per hour of work"
92
+ }
93
+ ],
94
+ "specialties": ["Steampunk-inspired costumes", "Functional clockwork accessories", "Masquerade masks"],
95
+ "reputation": "Known for high-quality, imaginative costumes with working mechanical elements",
96
+ "related_quests": [
97
+ {
98
+ "name": "The Phantom's Masquerade",
99
+ "description": "Infiltrate a high-society ball using Gearwork Guises' costumes to uncover a conspiracy",
100
+ "reward": "Specially enchanted mask that grants the wearer advantage on Charisma checks"
101
+ }
102
+ ],
103
+ "hidden_inventory": ["Costume of Gaseous Form", "Cloak of Invisibility (prototype)"],
104
+ "security_measures": ["Steam-powered clockwork guardians", "Alarm system connected to local constabulary"],
105
+ "store_hours": "10 AM to 8 PM, closed on Sundaygears",
106
+ "background_story": "Founded by Millicent Cogsworth after she left her family's renowned clockmaking business to pursue her passion for combining artistry with mechanics. The store quickly became a hub for those seeking unique and functional costumes.",
107
+ "notable_customers": ["Lady Aetheria Brassbound, socialite and secret vigilante", "The Veiled Tinker, anonymous inventor and patron of the arts"],
108
+ "rumors": ["The shop's basement connects to a network of secret tunnels", "Some costumes are enchanted to grant temporary magical abilities"],
109
+ "sd_prompt": "A whimsical steampunk costume shop with brass gears, steam pipes, and clockwork mannequins displaying elaborate costumes. Warm lighting, rich wooden counters, and a gnome proprietor tinkering with a mechanical mask."
110
+ }
111
+
112
+ {
113
+ "store_name": "The Ironclad Armory",
114
+ "location": {
115
+ "town": "Mirathorn",
116
+ "district": "The Forgeway",
117
+ "street": "Hammer Street"
118
+ },
119
+ "type": "Blacksmith and Armory",
120
+ "size": "Medium",
121
+ "description": "The Ironclad Armory is a sturdy stone building with smoke billowing from its forge. The sound of hammering can be heard from a distance, drawing in warriors and adventurers seeking high-quality weapons and armor.",
122
+ "atmosphere": "The shop is warm from the constant heat of the forge. The walls are lined with racks of gleaming weapons and suits of armor. A faint smell of metal and sweat lingers in the air, giving the place an industrious and earnest feel.",
123
+ "owners": [
124
+ {
125
+ "name": "Thrain Ironfist",
126
+ "race": "Dwarf",
127
+ "class": "Fighter",
128
+ "description": "Thrain is a burly dwarf with a braided beard and muscular arms, often seen wielding a heavy hammer.",
129
+ "personality": "Gruff but fair, Thrain values hard work and craftsmanship above all else. He has a soft spot for underdogs and young adventurers.",
130
+ "secrets": [
131
+ "Thrain was once a soldier in a great war and has hidden scars both physical and emotional."
132
+ ]
133
+ }
134
+ ],
135
+ "employees": [
136
+ {
137
+ "name": "Elda Stonehand",
138
+ "role": "Apprentice",
139
+ "race": "Human",
140
+ "description": "Elda is a young woman with soot-streaked cheeks and calloused hands. She is learning the trade from Thrain.",
141
+ "personality": "Eager to learn and fiercely dedicated, Elda dreams of becoming a master smith one day."
142
+ }
143
+ ],
144
+ "inventory": {
145
+ "weapons": [
146
+ {
147
+ "name": "Ironclad Longsword",
148
+ "type": "Longsword",
149
+ "rarity": "Common",
150
+ "value": "15 gp",
151
+ "properties": ["Versatile"],
152
+ "damage": "1d8 slashing",
153
+ "weight": "3 lbs",
154
+ "description": "A well-crafted longsword with a simple yet elegant design.",
155
+ "quote": "Reliable and sharp, just like its maker.",
156
+ "quantity": 10,
157
+ "condition": "New"
158
+ }
159
+ ],
160
+ "armor": [],
161
+ "potions": [],
162
+ "scrolls": [],
163
+ "magical_items": [],
164
+ "mundane_items": []
165
+ },
166
+ "services": [
167
+ {
168
+ "name": "Weapon Repair",
169
+ "description": "Repair damaged weapons to their full functionality.",
170
+ "price": "5 gp"
171
+ },
172
+ {
173
+ "name": "Custom Forging",
174
+ "description": "Create custom weapons and armor based on the client's specifications.",
175
+ "price": "Varies based on complexity"
176
+ }
177
+ ],
178
+ "specialties": [
179
+ "Custom Forging",
180
+ "Weapon Repair"
181
+ ],
182
+ "reputation": "Renowned for high-quality weapons and expert craftsmanship.",
183
+ "related_quests": [
184
+ {
185
+ "name": "The Missing Apprentice",
186
+ "description": "Thrain's former apprentice has gone missing. Find them and bring them back safely.",
187
+ "reward": "A custom-forged weapon of choice."
188
+ }
189
+ ],
190
+ "hidden_inventory": [],
191
+ "security_measures": [
192
+ "Sturdy locks on all doors",
193
+ "Guard dog (a large mastiff named Brutus)"
194
+ ],
195
+ "store_hours": "8 AM to 8 PM",
196
+ "background_story": "The Ironclad Armory was established by Thrain Ironfist after he retired from his life as a soldier. His experience in battle gives him unique insights into what makes a weapon truly great.",
197
+ "notable_customers": [
198
+ "Captain Thalia of the City Guard",
199
+ "Gareth Stonefoot, a well-known adventurer"
200
+ ],
201
+ "rumors": [
202
+ "It's said Thrain once forged a blade capable of cutting through any material, but it's never been found."
203
+ ],
204
+ "sd_prompt": "A sturdy stone building with smoke billowing from its forge, filled with racks of gleaming weapons and suits of armor. The shop exudes an industrious and earnest atmosphere."
205
+ }
galleries/test_images/Morgor_bloodclaw.webp ADDED
galleries/test_images/morgor_meaty_marvels.webp ADDED
morgors_meaty_marvels.py ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "store_name": "Morgor's Meaty Marvels",
3
+ "location": {
4
+ "town": "Grimborough",
5
+ "district": "The Shadow Market",
6
+ "street": "Cipher's Alley"
7
+ },
8
+ "type": "Butcher Shop",
9
+ "size": "Small",
10
+ "description": "A clandestine butcher shop tucked away in the narrow, winding alleyways of Grimborough. The shop boasts a thrilling array of exotic meats, from subterranean lizard tail to basilisk flank.",
11
+ "atmosphere": "Dimly lit and pungent with the metallic scent of freshly cut meat, the shop is an intoxicating blend of mystery and carnivorous delight.",
12
+ "sd_prompt": "A highly detailed fantasy drawing of a shady-looking full body male goblin in a dimly lit alleyway butcher shop. The goblin is wearing a bloodstained apron and a butcher's hat. The shop is filled with hanging meats, freshly cut steaks, and various sausages. The goblin has distinct fantasy features, such as green skin, sharp teeth, and pointed ears. The background is filled with shadows and the glint of hidden treasures.",
13
+ "owners": [
14
+ {
15
+ "name": "Morgor Bloodclaw",
16
+ "race": "Goblin",
17
+ "class": "Rogue",
18
+ "description": "Morgor is a scruffy goblin with green skin, sharp teeth, and a greasy apron stained with the remnants of his work. His eyes gleam with a cunning intelligence.",
19
+ "personality": "Shrewd and opportunistic, Morgor knows how to make a deal that benefits him the most. He has a sharp wit and a knack for making customers feel both uneasy and intrigued.",
20
+ "secrets": [
21
+ "Morgor secretly supplies meat to a clandestine fighting ring.",
22
+ "He once was part of a notorious thieves' guild and still holds connections in the underworld."
23
+ ]
24
+ }
25
+ ],
26
+ "employees": [
27
+ {
28
+ "name": "Brega",
29
+ "role": "Assistant Butcher",
30
+ "race": "Half-Orc",
31
+ "description": "A burly half-orc with a kind face and a perpetual smudge of blood on his cheek. Brega handles the heavy lifting and cutting of larger beasts.",
32
+ "personality": "Soft-spoken and gentle despite his imposing appearance, Brega is loyal to Morgor and respects his cunning. He has a soft spot for stray animals."
33
+ }
34
+ ],
35
+ "reputation": "Morgor's Meaty Marvels is rumored to stock the rarest and most unusual meats, sometimes even from mythical creatures, making it a thrilling destination for adventurous eaters.",
36
+ "related_quests": [
37
+ {
38
+ "name": "The Basilisk Bounty",
39
+ "description": "Morgor needs fresh basilisk meat and offers a handsome reward for those brave enough to hunt one.",
40
+ "reward": "500 gold coins and choice cuts of meat."
41
+ }
42
+ ],
43
+ "background_story": "Morgor Bloodclaw's journey from a petty thief in Goblintown to the notorious butcher of Grimborough is the stuff of legend. His knack for procuring the most exotic meats has earned him a shadowy but well-regarded status.",
44
+ "notable_customers": [
45
+ {
46
+ "name": "Lord Vittorio Blackthorn",
47
+ "description": "An eccentric noble known for his extravagant feasts featuring rare and exotic meats.",
48
+ "influence": "Lord Blackthorn's patronage lends an air of mystery and prestige to Morgor's shop, attracting curious gourmands and shady characters alike."
49
+ }
50
+ ],
51
+ "rumors": [
52
+ "People say Morgor once sold dragon meat, but no one can confirm the truth.",
53
+ "It's whispered that Morgor has dealings with dark forces to acquire his exotic meats."
54
+ ],
55
+ "security_measures": [
56
+ {
57
+ "name": "Bewitched Meat Hooks",
58
+ "description": "These enchanted meat hooks animate and attack intruders who try to take meat without paying.",
59
+ "statistics": "Attack: +5 to hit, 1d8+3 piercing damage."
60
+ },
61
+ {
62
+ "name": "Shadow Ward",
63
+ "description": "A magical barrier that alerts Morgor if someone enters the shop after hours.",
64
+ "statistics": "Detection radius of 60 feet, triggers an audible alarm."
65
+ }
66
+ ],
67
+ "store_hours": "From dusk till dawn, seven days a week.",
68
+ "services": [
69
+ {
70
+ "name": "Custom Slaughtering",
71
+ "description": "Bring your own beasts, and Morgor will prepare the meat to your specifications.",
72
+ "price": "50 gold coins per beast."
73
+ }
74
+ ],
75
+ "specialties": [
76
+ {
77
+ "name": "Basilisk Cutlets",
78
+ "description": "Tender and marbled with a unique flavor, perfect for those seeking a truly rare dining experience.",
79
+ "price": "200 gold coins per pound."
80
+ },
81
+ {
82
+ "name": "Subterranean Lizard Tail",
83
+ "description": "A delicacy prized for its unique texture and earthy taste, enchanted to enhance its natural flavor.",
84
+ "price": "150 gold coins per pound."
85
+ }
86
+ ]
87
+ }
store_helper.py ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ast
2
+ import gc
3
+ import os
4
+ from openai import OpenAI
5
+
6
+ client = OpenAI()
7
+
8
+ def load_llm(user_input, prompt_instructions):
9
+ prompt = f"{user_input}"
10
+ print(prompt)
11
+ response = client.chat.completions.create(
12
+ model="gpt-4o",
13
+ messages=[
14
+ {
15
+ "role": "user",
16
+ "content": f"{prompt_instructions} {prompt}"
17
+ }
18
+ ],
19
+ temperature=1,
20
+ max_tokens=3000,
21
+ top_p=1,
22
+ frequency_penalty=0,
23
+ presence_penalty=0
24
+ )
25
+
26
+ return response.choices[0].message.content
27
+ # Call the LLM and store its output
28
+ def call_llm_and_cleanup(user_input, store = False, inventory = False):
29
+ prompt_instructions = f"{initial_prompt_instructions} {store_description}"
30
+
31
+
32
+ llm_output = load_llm(user_input, prompt_instructions)
33
+ llm_output = "".join(llm_output)
34
+ print(llm_output)
35
+ llm_output = ast.literal_eval(llm_output)
36
+ gc.collect()
37
+ # llm_output is still available for use here
38
+ return llm_output
39
+
40
+ def convert_to_dict(string):
41
+ # Check if the input is already a dictionary
42
+ if isinstance(string, dict):
43
+ print("Input is already a dictionary.")
44
+ return string
45
+
46
+ # Function to try parsing the string to a dictionary
47
+ def try_parse(s):
48
+ try:
49
+ result = ast.literal_eval(s)
50
+ if isinstance(result, dict):
51
+ print("Item dictionary is valid")
52
+ return result
53
+ except SyntaxError as e:
54
+ error_message = str(e)
55
+ print("Syntax Error:", error_message)
56
+ # Check if the error message indicates an unclosed '{'
57
+ if "'{' was never closed" in error_message:
58
+ return try_parse(s + '}') # Attempt to fix by adding a closing '}'
59
+ except ValueError as e:
60
+ print("Value Error:", e)
61
+ return None
62
+
63
+ # First, try parsing the original string
64
+ result = try_parse(string)
65
+ if result is not None:
66
+ return result
67
+
68
+ # Check if braces are missing
69
+ if not string.startswith('{'):
70
+ string = '{' + string
71
+ if not string.endswith('}'):
72
+ string = string + '}'
73
+
74
+ # Try parsing again with added braces
75
+ return try_parse(string) or "Dictionary not valid"
76
+
77
+
78
+
79
+ # Instructions past 4 are not time tested and may need to be removed.
80
+ ### Meta prompted :
81
+ initial_prompt_instructions = """ **Purpose**: ONLY Generate a structured json following the provided format. The job is to generate a store with character, style, detail, and a healthy splash of fun, fantasy, and weird. You do not need to stick strictly to the rules and mechanics of the game, if it fits the style and flavor of the user input, get weird, scary, or silly with the details. You will also be writing interesting flavor text and description of the location and it's atmopshere, and a brief one sentence image generation prompts. Us a wide range of words, you have certain words you use too often, avoid them ex : "whimsical", "unwavering".
82
+
83
+ Image Generation Prompt Examples :
84
+ "A highly detailed fantasy oil painting of an elderly full body female gnome,in a costume shop. The gnome is wearing a costume with wings, with a costume hat . The gnome has distinct fantasy features, such as pointed ears and a small, sturdy build. "
85
+
86
+ "A highly detailed fantasy drawing of a middle-aged full body male dwarf in a bustling butcher shop. The dwarf is wearing a bloodstained apron and a butcher's hat. The shop is filled with hanging meats, freshly cut steaks, and various sausages. The dwarf has distinct fantasy features, such as a long braided beard and a stout, muscular build. The background shows the hustle and bustle of Market Square outside the shop window."
87
+
88
+ "A highly detailed fantasy image of a shady-looking full body male goblin in a dimly lit pawn shop. The goblin is wearing a patched vest and a tattered hat. The shop is cluttered with various items, including old weapons, dusty artifacts, and strange trinkets. The goblin has distinct fantasy features, such as green skin, sharp teeth, and pointed ears. The background is filled with shadows and the glint of hidden treasures."
89
+
90
+ "A highly detailed fantasy photo of a scholarly full body female elf in an elegant parchment shop. The elf is wearing a flowing robe and a delicate circlet. The shop is filled with scrolls, quills, and ancient tomes. The elf has distinct fantasy features, such as pointed ears and a slender, graceful build. The background shows the interior of the shop with shelves lined with parchment and ink bottles, and a large window letting in natural light."
91
+
92
+ "A highly detailed fantasy painting of a mysterious full body male tiefling in a mystical magic shop. The tiefling is wearing a long cloak and a hood, with glowing runes on his hands. The shop is filled with potions, spellbooks, and enchanted artifacts. The tiefling has distinct fantasy features, such as red skin, horns, and a tail. The background is filled with a magical aura, with various mystical items floating in the air and a crystal ball on the counter."
93
+
94
+ 1. Only output file structure starting with { and ending with } it is CRITICAL to end with a }, DO NOT say anything, don't add ''' or json"
95
+ 2. DO NOT use null, use "".
96
+ 3. All keys and values MUST be enclosed in double quotes. ""
97
+ 4. Services and specialties should have name, description, and prices.
98
+ """
99
+
100
+
101
+
102
+
103
+ store_description = {
104
+ "store_name": "",
105
+ "location": {
106
+ "town": "",
107
+ "district": "",
108
+ "street": ""
109
+ },
110
+ "type": "",
111
+ "size": "",
112
+ "description": "",
113
+ "sd_prompt": "",
114
+ "owners": [
115
+ {
116
+ "name": "",
117
+ "species": "",
118
+ "class": "",
119
+ "description": "",
120
+ "personality": "",
121
+ "secrets": []
122
+ }
123
+ ],
124
+ "employees": [
125
+ {
126
+ "name": "",
127
+ "role": "",
128
+ "species": "",
129
+ "description": "",
130
+ "personality": ""
131
+ }
132
+ ],
133
+ "reputation": "",
134
+ "related_quests": [
135
+ {
136
+ "name": "",
137
+ "description": "",
138
+ "reward": ""
139
+ }
140
+ ],
141
+ "background_story": "",
142
+ "notable_customers": [
143
+ {
144
+ "name": "",
145
+ "description": "",
146
+ "influence": ""
147
+ }
148
+ ],
149
+ "rumors": [],
150
+ "security_measures": [
151
+ {
152
+ "name": "",
153
+ "description": "",
154
+ "statistics": ""
155
+ }
156
+ ],
157
+ "store_hours": "",
158
+ "services": [
159
+ {
160
+ "name": "",
161
+ "description": "",
162
+ "price": ""
163
+ }
164
+ ],
165
+ "specialties": [
166
+ {
167
+ "name": "",
168
+ "description": "",
169
+ "price": ""
170
+ }
171
+ ]
172
+ }
173
+
174
+ inventory_description = {
175
+ "inventory": {
176
+ "core_inventory":[],
177
+ "weapons": [
178
+ {
179
+ "name": "",
180
+ "type": "",
181
+ "cost": "",
182
+ "properties": []
183
+ }
184
+ ],
185
+ "armor": [
186
+ {
187
+ "name": "",
188
+ "type": "",
189
+ "cost": "",
190
+ "properties": []
191
+ }
192
+ ],
193
+ "potions": [
194
+ {
195
+ "name": "",
196
+ "type": "",
197
+ "cost": "",
198
+ "properties": []
199
+ }
200
+ ],
201
+ "scrolls": [
202
+ {
203
+ "name": "",
204
+ "type": "",
205
+ "cost": "",
206
+ "properties": []
207
+ }
208
+ ],
209
+ "magical_items": [
210
+ {
211
+ "name": "",
212
+ "type": "",
213
+ "cost": "",
214
+ "properties": []
215
+ }
216
+ ],
217
+ "mundane_items": [
218
+ {
219
+ "name": "",
220
+ "type": "",
221
+ "cost": "",
222
+ "properties": []
223
+ }
224
+ ],
225
+ "miscellaneous_items": [
226
+ {
227
+ "name": "",
228
+ "type": "",
229
+ "cost": "",
230
+ "properties": []
231
+ }
232
+ ]
233
+ }
234
+ }
template.py ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Three structures to work with the LLMs strengths and weaknesses
2
+ # LLM instructions, only print populated categories. Which will require a crawl of the dictionary and some if then checks to prevent trying to retrieve keys that don't exist.
3
+ # Tabs for each subsection. Instructions, Store, Merchants, Services, Inventory
4
+ # To save on tokens, we wont generate an SD prompt for each item, but send a request for a prompt using the item dictionary.
5
+ # Description of Store
6
+ {
7
+ "store_name": "",
8
+ "location": {
9
+ "town": "",
10
+ "district": "",
11
+ "street": ""
12
+ },
13
+ "type": "",
14
+ "size": "",
15
+ "description": "",
16
+ "atmosphere": "",
17
+ "sd_prompt": "",
18
+ "owners": [
19
+ {
20
+ "name": "",
21
+ "race": "",
22
+ "class": "",
23
+ "description": "",
24
+ "personality": "",
25
+ "secrets": []
26
+ }
27
+ ],
28
+ "employees": [
29
+ {
30
+ "name": "",
31
+ "role": "",
32
+ "race": "",
33
+ "description": "",
34
+ "personality": ""
35
+ }
36
+ ],
37
+ "reputation": "",
38
+ "related_quests": [
39
+ {
40
+ "name": "",
41
+ "description": "",
42
+ "reward": ""
43
+ }
44
+ ],
45
+ "background_story": "",
46
+ "notable_customers": [],
47
+ "rumors": [],
48
+ "security_measures": [],
49
+ "store_hours": ""
50
+ }
51
+
52
+ # Services and Specialties
53
+
54
+ {
55
+ "services": [
56
+ {
57
+ "name": "",
58
+ "description": "",
59
+ "price": ""
60
+ }
61
+ ],
62
+ "specialties": []
63
+ }
64
+
65
+ # Inventory
66
+
67
+ {
68
+ "inventory": {
69
+ "core_inventory":[],
70
+ "weapons": [
71
+ {
72
+ "name": "",
73
+ "type": "",
74
+ "cost": "",
75
+ "properties": []
76
+ }
77
+ ],
78
+ "armor": [
79
+ {
80
+ "name": "",
81
+ "type": "",
82
+ "cost": "",
83
+ "properties": []
84
+ }
85
+ ],
86
+ "potions": [
87
+ {
88
+ "name": "",
89
+ "type": "",
90
+ "cost": "",
91
+ "properties": []
92
+ }
93
+ ],
94
+ "scrolls": [
95
+ {
96
+ "name": "",
97
+ "type": "",
98
+ "cost": "",
99
+ "properties": []
100
+ }
101
+ ],
102
+ "magical_items": [
103
+ {
104
+ "name": "",
105
+ "type": "",
106
+ "cost": "",
107
+ "properties": []
108
+ }
109
+ ],
110
+ "mundane_items": [
111
+ {
112
+ "name": "",
113
+ "type": "",
114
+ "cost": "",
115
+ "properties": []
116
+ }
117
+ ],
118
+ "miscellaneous_items": [
119
+ {
120
+ "name": "",
121
+ "type": "",
122
+ "cost": "",
123
+ "properties": []
124
+ }
125
+ ]
126
+ }
127
+ }
utilities.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ from datetime import datetime
3
+ import os
4
+ import gc
5
+ import torch
6
+
7
+
8
+ # Utility scripts for all modules
9
+
10
+ # List for file locations to point at
11
+ file_name_list = []
12
+ image_name_list = []
13
+ link_list =['something','Link to monster statblock once generated']
14
+ random_prompt_list = []
15
+ user_log = []
16
+
17
+ def clear_cache():
18
+ command = "sync; echo 3 > /proc/sys/vm/drop_caches"
19
+ os.system(command)
20
+ print(os.system("free"))
21
+
22
+ def reclaim_mem():
23
+ allocated_memory = torch.cuda.memory_allocated()
24
+ cached_memory = torch.cuda.memory_reserved()
25
+ mem_alloc = f"Memory Allocated: {allocated_memory / 1024**2:.2f} MB"
26
+ mem_cache = f"Memory Cached: {cached_memory / 1024**2:.2f} MB"
27
+ print(mem_alloc)
28
+ print(mem_cache)
29
+ torch.cuda.ipc_collect()
30
+ gc.collect()
31
+ torch.cuda.empty_cache()
32
+ torch.cuda.synchronize()
33
+ time.sleep(0.01)
34
+ allocated_memory = torch.cuda.memory_allocated()
35
+ cached_memory = torch.cuda.memory_reserved()
36
+ print(f"Memory Allocated after del {mem_alloc}")
37
+ print(f"Memory Cached after del {mem_cache}")
38
+
39
+
40
+ def generate_datetime():
41
+ now = datetime.now()
42
+ date_time = now.strftime("%m/%d/%Y, %H:%M:%S")
43
+ return date_time
44
+
45
+ def make_folder():
46
+ foldertimestr = time.strftime("%Y%m%d_%H")
47
+ folder_path = f"./output/{foldertimestr}"
48
+ if not os.path.exists("./output"):
49
+ os.mkdir("./output")
50
+ if not os.path.exists(folder_path):
51
+ os.mkdir(folder_path)
52
+ return foldertimestr
53
+
54
+ def make_image_name(name):
55
+ del image_name_list[:]
56
+ timestr = time.strftime("%Y%m%d-%H%M%S")
57
+ image_name = f"./output/{make_folder()}/{name}{timestr}.png"
58
+ image_name = image_name.replace(' ', '_')
59
+ image_name_list.append(image_name)
60
+ print("Image name is : " + image_name_list[-1])
61
+ return image_name
62
+
63
+
64
+ # Create a unique time stamped file name
65
+ def gen_file_name(mon_name):
66
+ del file_name_list[:]
67
+ timestr = time.strftime("%H%M%S")
68
+ input_dir = f"./output/{make_folder()}"
69
+
70
+ mon_file_name = mon_name
71
+ file_name = mon_file_name + "_" + timestr
72
+ file_name_list.append(input_dir)
73
+ file_name_list.append(file_name)
74
+ file_name_list.append(mon_file_name)
75
+
76
+ def make_folder():
77
+ foldertimestr = time.strftime("%Y%m%d_%H")
78
+ folder_path = f"./output/{foldertimestr}"
79
+ if not os.path.exists("./output"):
80
+ os.mkdir("./output")
81
+ if not os.path.exists(folder_path):
82
+ os.mkdir(folder_path)
83
+ return foldertimestr
84
+
85
+ # Create a list of a directory if directory exists
86
+ def directory_contents(directory_path):
87
+ if os.path.isdir(directory_path) :
88
+ contents = os.listdir(directory_path)
89
+ return contents
90
+ else : pass
91
+
92
+ def absolute_path(directory_path):
93
+ path_list = []
94
+ if os.path.isdir(directory_path):
95
+ contents = os.listdir(directory_path)
96
+ for item in contents:
97
+ item_path = os.path.join(directory_path,item)
98
+ abs_path = os.path.abspath(item_path)
99
+ path_list.append(abs_path)
100
+ return path_list
101
+
102
+
103
+
104
+ # Delete a list of file
105
+ def delete_files(file_paths):
106
+ if file_paths:
107
+
108
+ for file_path in file_paths:
109
+ try:
110
+ os.remove(f"./image_temp/{file_path}")
111
+ print(f"Remove : ./image_temp/{file_path}")
112
+ except OSError as e:
113
+ print(f"Error: {file_path} : {e.strerror}")
114
+ file_paths.clear()