azils3 commited on
Commit
4d96073
β€’
1 Parent(s): afc4ce6

Update TextGen/router.py

Browse files
Files changed (1) hide show
  1. TextGen/router.py +158 -158
TextGen/router.py CHANGED
@@ -3,14 +3,14 @@ import time
3
  from io import BytesIO
4
  from langchain_core.pydantic_v1 import BaseModel, Field
5
  from fastapi import FastAPI, HTTPException, Query, Request
6
- from fastapi.responses import StreamingResponse,Response
7
  from fastapi.middleware.cors import CORSMiddleware
8
 
9
  from langchain.chains import LLMChain
10
  from langchain.prompts import PromptTemplate
11
- from TextGen.suno import custom_generate_audio, get_audio_information,generate_lyrics
12
- #from TextGen.diffusion import generate_image
13
- #from coqui import predict
14
  from langchain_google_genai import (
15
  ChatGoogleGenerativeAI,
16
  HarmBlockThreshold,
@@ -22,13 +22,12 @@ from typing import List
22
  from elevenlabs.client import ElevenLabs
23
  from elevenlabs import Voice, VoiceSettings, stream
24
 
25
-
26
  Eleven_client = ElevenLabs(
27
- api_key=os.environ["ELEVEN_API_KEY"], # Defaults to ELEVEN_API_KEY
28
  )
29
 
 
30
 
31
- Last_message=None
32
  class PlayLastMusic(BaseModel):
33
  '''plays the lastest created music '''
34
  Desicion: str = Field(
@@ -36,85 +35,88 @@ class PlayLastMusic(BaseModel):
36
  )
37
 
38
  class CreateLyrics(BaseModel):
39
- f'''create some Lyrics for a new music'''
40
  Desicion: str = Field(
41
  ..., description="Yes or No"
42
  )
43
 
44
  class CreateNewMusic(BaseModel):
45
- f'''create a new music with the Lyrics previously computed'''
46
  Name: str = Field(
47
  ..., description="tags to describe the new music"
48
  )
49
 
50
  class SongRequest(BaseModel):
51
- prompt: str | None = None
52
  tags: List[str] | None = None
53
 
54
  class Message(BaseModel):
55
- npc: str | None = None
56
  messages: List[str] | None = None
 
57
  class ImageGen(BaseModel):
58
- prompt: str | None = None
 
59
  class VoiceMessage(BaseModel):
60
- npc: str | None = None
61
  input: str | None = None
62
  language: str | None = "en"
63
- genre:str | None = "Male"
64
-
65
- song_base_api=os.environ["VERCEL_API"]
66
 
67
- my_hf_token=os.environ["HF_TOKEN"]
 
68
 
69
- #tts_client = Client("Jofthomas/xtts",hf_token=my_hf_token)
70
 
71
- main_npcs={
72
- "Blacksmith":"./voices/Blacksmith.mp3",
73
- "Herbalist":"./voices/female.mp3",
74
- "Bard":"./voices/Bard_voice.mp3"
75
  }
76
- main_npcs_elevenlabs={
77
- "Blacksmith":"yYdk7n49vTsUKiXxnosS",
78
- "Herbalist":"143zSsxc4O5ifS97lPCa",
79
- "Bard":"143zSsxc4O5ifS97lPCa"
 
80
  }
81
- main_npc_system_prompts={
82
- "Blacksmith":"You are a blacksmith in a video game",
83
- "Herbalist":"You are an herbalist in a video game",
84
- "Witch":"You are a witch in a video game. You are disguised as a potion seller in a small city where adventurers come to challenge the portal. You are selling some magic spells in a UI that the player only sees. Don't event too much lore and just follow the standard role of a merchant.",
85
- "Bard":"You are a bard in a video game"
 
86
  }
 
87
  class Generate(BaseModel):
88
- text:str
89
 
90
  class Rooms(BaseModel):
91
- rooms:List
92
- room_of_interest:List
93
- index_exit:int
94
- possible_entities:List
95
- logs:List
96
 
97
  class Room_placements(BaseModel):
98
- placements:dict
99
-
100
 
101
  class Invoke(BaseModel):
102
- system_prompt:str
103
- message:str
104
 
105
- def generate_text(messages: List[str], npc:str):
106
  print(npc)
107
  if npc in main_npcs:
108
- system_prompt=main_npc_system_prompts[npc]
109
  else:
110
- system_prompt="you're a character in a video game. Play along."
111
- print(system_prompt)
112
- new_messages=[{"role": "user", "content": system_prompt}]
113
  for index, message in enumerate(messages):
114
- if index%2==0:
115
- new_messages.append({"role": "user", "content": message})
116
- else:
117
- new_messages.append({"role": "assistant", "content": message})
118
  print(new_messages)
119
  # Initialize the LLM
120
  llm = ChatGoogleGenerativeAI(
@@ -122,14 +124,14 @@ def generate_text(messages: List[str], npc:str):
122
  max_output_tokens=100,
123
  temperature=1,
124
  safety_settings={
125
- HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: HarmBlockThreshold.BLOCK_NONE,
126
- HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_NONE,
127
- HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_NONE,
128
- HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: HarmBlockThreshold.BLOCK_NONE
129
- },
130
  )
131
- if npc=="bard":
132
- llm = llm.bind_tools([PlayLastMusic,CreateNewMusic,CreateLyrics])
133
 
134
  llm_response = llm.invoke(new_messages)
135
  print(llm_response)
@@ -144,18 +146,17 @@ app.add_middleware(
144
  )
145
 
146
  def inference_model(system_messsage, prompt):
147
-
148
- new_messages=[{"role": "user", "content": system_messsage},{"role": "user", "content": prompt}]
149
  llm = ChatGoogleGenerativeAI(
150
  model="gemini-1.5-pro-latest",
151
  max_output_tokens=100,
152
  temperature=1,
153
  safety_settings={
154
- HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: HarmBlockThreshold.BLOCK_NONE,
155
- HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_NONE,
156
- HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_NONE,
157
- HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: HarmBlockThreshold.BLOCK_NONE
158
- },
159
  )
160
  llm_response = llm.invoke(new_messages)
161
  print(llm_response)
@@ -171,71 +172,70 @@ def inference(message: Message):
171
 
172
  @app.post("/invoke_model")
173
  def story(prompt: Invoke):
174
- return inference_model(system_messsage=prompt.system_prompt,prompt=prompt.message)
175
-
176
  @app.post("/generate_level")
177
  def placement(input: Rooms):
178
  print(input)
179
- markdown_map=generate_map_markdown(input)
180
  print(markdown_map)
181
- answer={
182
- "key":"value"
183
  }
184
  return answer
185
 
186
- #Dummy function for now
187
- def determine_vocie_from_npc(npc,genre):
188
  if npc in main_npcs:
189
  return main_npcs[npc]
190
  else:
191
- if genre =="Male":
192
- "./voices/default_male.mp3"
193
- if genre=="Female":
194
- return"./voices/default_female.mp3"
195
  else:
196
  return "./voices/narator_out.wav"
197
- #Dummy function for now
198
- def determine_elevenLav_voice_from_npc(npc,genre):
 
199
  if npc in main_npcs_elevenlabs:
200
  return main_npcs_elevenlabs[npc]
201
  else:
202
- if genre =="Male":
203
- "bIHbv24MWmeRgasZH58o"
204
- if genre=="Female":
205
- return"pFZP5JQG7iQjIQuC4Bku"
206
  else:
207
- return "TX3LPaxmHKxFdv7VOQHJ"
208
 
209
- @app.post("/generate_wav")
210
  async def generate_wav(message: VoiceMessage):
211
- # try:
212
- # voice = determine_vocie_from_npc(message.npc, message.genre)
213
- # audio_file_pth = handle_file(voice)
214
- #
215
  # Generator function to yield audio chunks
216
- # async def audio_stream():
217
- # result = tts_client.predict(
218
- # prompt=message.input,
219
- # language=message.language,
220
- # audio_file_pth=audio_file_pth,
221
- # mic_file_path=None,
222
- # use_mic=False,
223
- # voice_cleanup=False,
224
- # no_lang_auto_detect=False,
225
- # agree=True,
226
- # api_name="/predict"
227
- # )
228
- # for sampling_rate, audio_chunk in result:
229
- # yield audio_chunk.tobytes()
230
- # await asyncio.sleep(0) # Yield control to the event loop
231
 
232
  # Return the generated audio as a streaming response
233
- # return StreamingResponse(audio_stream(), media_type="audio/wav")
234
-
235
- # except Exception as e:
236
- # raise HTTPException(status_code=500, detail=str(e))
237
- return 200
238
 
 
 
239
 
240
  @app.get("/generate_voice_eleven", response_class=StreamingResponse)
241
  @app.post("/generate_voice_eleven", response_class=StreamingResponse)
@@ -247,8 +247,8 @@ def generate_voice_eleven(message: VoiceMessage = None):
247
  Last_message = message
248
 
249
  def audio_stream():
250
- this_voice_id=determine_elevenLav_voice_from_npc(message.npc, message.genre)
251
-
252
  # Generate the audio stream from ElevenLabs
253
  for chunk in Eleven_client.generate(text=message.input,
254
  voice=Voice(
@@ -259,66 +259,66 @@ def generate_voice_eleven(message: VoiceMessage = None):
259
  yield chunk
260
 
261
  return StreamingResponse(audio_stream(), media_type="audio/mpeg")
262
- #@app.get("/generate_voice_coqui", response_class=StreamingResponse)
263
- #@app.post("/generate_voice_coqui", response_class=StreamingResponse)
264
- #def generate_voice_coqui(message: VoiceMessage = None):
265
- # global Last_message
266
- # if message is None:
267
- # message = Last_message
268
- # else:
269
- # Last_message = message
 
270
  #
271
- # def audio_stream():
272
- # voice = determine_vocie_from_npc(message.npc, message.genre)
273
- # result = predict(
274
- # prompt=message.input,
275
- # language=message.language,
276
- # audio_file_pth=voice,
277
- # mic_file_path=None,
278
- # use_mic=False,
279
- # voice_cleanup=False,
280
- # no_lang_auto_detect=False,
281
- # agree=True,
282
- # )
283
- # # Generate the audio stream from ElevenLabs
284
- # for chunk in result:
285
- # print("received : ",chunk)
286
- # yield chunk#
287
  #
288
- # return StreamingResponse(audio_stream(),media_type="audio/mpeg")
 
289
  @app.get("/generate_song")
290
  async def generate_song():
291
- text="""You are a bard in a video game singing the tales of a little girl in red hood."""
292
 
293
- song_lyrics=generate_lyrics({
294
  "prompt": f"{text}",
295
- })
296
  data = custom_generate_audio({
297
  "prompt": song_lyrics['text'],
298
  "tags": "male bard",
299
- "title":"Everchangin_Quest_song",
300
- "wait_audio":True,
301
-
302
  })
303
- infos=get_audio_information(f"{data[0]['id']},{data[1]['id']}")
304
  return infos
305
 
306
- #@app.post('/generate_image')
307
- #def Imagen(image:ImageGen=None):
308
- # pil_image =generate_image(image.prompt)
309
- #
310
  #
311
- # # Convert the PIL Image to bytes
312
- # img_byte_arr = BytesIO()
313
- # pil_image.save(img_byte_arr, format='PNG')
314
- # img_byte_arr = img_byte_arr.getvalue()
315
  #
316
- # Return the image as a PNG response
317
- # return Response(content=img_byte_arr, media_type="image/png")
318
 
319
  def generate_map_markdown(data):
320
  import numpy as np
321
-
322
  # Define the room structure with walls and markers
323
  def create_room(room_char):
324
  return [
@@ -326,22 +326,22 @@ def generate_map_markdown(data):
326
  f"β•‘ {room_char} β•‘",
327
  f"β•šβ•β•β•β•"
328
  ]
329
-
330
  # Extract rooms and rooms of interest
331
  rooms = [eval(room) for room in data["rooms"]]
332
  rooms_of_interest = [eval(room) for room in data["room_of_interest"]]
333
-
334
  # Determine grid size
335
  min_x = min(room[0] for room in rooms)
336
  max_x = max(room[0] for room in rooms)
337
  min_y = min(room[1] for room in rooms)
338
  max_y = max(room[1] for room in rooms)
339
-
340
  # Create grid with empty spaces represented by a room-like structure
341
  map_height = (max_y - min_y + 1) * 3
342
  map_width = (max_x - min_x + 1) * 5
343
  grid = np.full((map_height, map_width), " ")
344
-
345
  # Populate grid with rooms and their characteristics
346
  for i, room in enumerate(rooms):
347
  x, y = room
@@ -356,9 +356,9 @@ def generate_map_markdown(data):
356
  room_structure = create_room(room_char)
357
  for j, row in enumerate(room_structure):
358
  grid[y_offset + j, x_offset:x_offset + 5] = list(row)
359
-
360
  # Convert grid to a string format suitable for display
361
  markdown_map = "\n".join("".join(row) for row in grid)
362
-
363
  # Return the map wrapped in triple backticks for proper display in markdown
364
  return f"```\n{markdown_map}\n```"
 
3
  from io import BytesIO
4
  from langchain_core.pydantic_v1 import BaseModel, Field
5
  from fastapi import FastAPI, HTTPException, Query, Request
6
+ from fastapi.responses import StreamingResponse, Response
7
  from fastapi.middleware.cors import CORSMiddleware
8
 
9
  from langchain.chains import LLMChain
10
  from langchain.prompts import PromptTemplate
11
+ from TextGen.suno import custom_generate_audio, get_audio_information, generate_lyrics
12
+ # from TextGen.diffusion import generate_image
13
+ # from coqui import predict
14
  from langchain_google_genai import (
15
  ChatGoogleGenerativeAI,
16
  HarmBlockThreshold,
 
22
  from elevenlabs.client import ElevenLabs
23
  from elevenlabs import Voice, VoiceSettings, stream
24
 
 
25
  Eleven_client = ElevenLabs(
26
+ api_key=os.environ["ELEVEN_API_KEY"], # Defaults to ELEVEN_API_KEY
27
  )
28
 
29
+ Last_message = None
30
 
 
31
  class PlayLastMusic(BaseModel):
32
  '''plays the lastest created music '''
33
  Desicion: str = Field(
 
35
  )
36
 
37
  class CreateLyrics(BaseModel):
38
+ '''create some Lyrics for a new music'''
39
  Desicion: str = Field(
40
  ..., description="Yes or No"
41
  )
42
 
43
  class CreateNewMusic(BaseModel):
44
+ '''create a new music with the Lyrics previously computed'''
45
  Name: str = Field(
46
  ..., description="tags to describe the new music"
47
  )
48
 
49
  class SongRequest(BaseModel):
50
+ prompt: str | None = None
51
  tags: List[str] | None = None
52
 
53
  class Message(BaseModel):
54
+ npc: str | None = None
55
  messages: List[str] | None = None
56
+
57
  class ImageGen(BaseModel):
58
+ prompt: str | None = None
59
+
60
  class VoiceMessage(BaseModel):
61
+ npc: str | None = None
62
  input: str | None = None
63
  language: str | None = "en"
64
+ genre: str | None = "Male"
 
 
65
 
66
+ song_base_api = os.environ["VERCEL_API"]
67
+ my_hf_token = os.environ["HF_TOKEN"]
68
 
69
+ tts_client = Client("Jofthomas/xtts", hf_token=my_hf_token)
70
 
71
+ main_npcs = {
72
+ "Blacksmith": "./voices/Blacksmith.mp3",
73
+ "Herbalist": "./voices/female.mp3",
74
+ "Bard": "./voices/Bard_voice.mp3"
75
  }
76
+
77
+ main_npcs_elevenlabs = {
78
+ "Blacksmith": "yYdk7n49vTsUKiXxnosS",
79
+ "Herbalist": "143zSsxc4O5ifS97lPCa",
80
+ "Bard": "143zSsxc4O5ifS97lPCa"
81
  }
82
+
83
+ main_npc_system_prompts = {
84
+ "Blacksmith": "You are a blacksmith in a video game",
85
+ "Herbalist": "You are an herbalist in a video game",
86
+ "Witch": "You are a witch in a video game. You are disguised as a potion seller in a small city where adventurers come to challenge the portal. You are selling some magic spells in a UI that the player only sees. Don't event too much lore and just follow the standard role of a merchant.",
87
+ "Bard": "You are a bard in a video game"
88
  }
89
+
90
  class Generate(BaseModel):
91
+ text: str
92
 
93
  class Rooms(BaseModel):
94
+ rooms: List
95
+ room_of_interest: List
96
+ index_exit: int
97
+ possible_entities: List
98
+ logs: List
99
 
100
  class Room_placements(BaseModel):
101
+ placements: dict
 
102
 
103
  class Invoke(BaseModel):
104
+ system_prompt: str
105
+ message: str
106
 
107
+ def generate_text(messages: List[str], npc: str):
108
  print(npc)
109
  if npc in main_npcs:
110
+ system_prompt = main_npc_system_prompts[npc]
111
  else:
112
+ system_prompt = "you're a character in a video game. Play along."
113
+ print(system_prompt)
114
+ new_messages = [{"role": "user", "content": system_prompt}]
115
  for index, message in enumerate(messages):
116
+ if index % 2 == 0:
117
+ new_messages.append({"role": "user", "content": message})
118
+ else:
119
+ new_messages.append({"role": "assistant", "content": message})
120
  print(new_messages)
121
  # Initialize the LLM
122
  llm = ChatGoogleGenerativeAI(
 
124
  max_output_tokens=100,
125
  temperature=1,
126
  safety_settings={
127
+ HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: HarmBlockThreshold.BLOCK_NONE,
128
+ HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_NONE,
129
+ HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_NONE,
130
+ HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: HarmBlockThreshold.BLOCK_NONE
131
+ },
132
  )
133
+ if npc == "bard":
134
+ llm = llm.bind_tools([PlayLastMusic, CreateNewMusic, CreateLyrics])
135
 
136
  llm_response = llm.invoke(new_messages)
137
  print(llm_response)
 
146
  )
147
 
148
  def inference_model(system_messsage, prompt):
149
+ new_messages = [{"role": "user", "content": system_messsage}, {"role": "user", "content": prompt}]
 
150
  llm = ChatGoogleGenerativeAI(
151
  model="gemini-1.5-pro-latest",
152
  max_output_tokens=100,
153
  temperature=1,
154
  safety_settings={
155
+ HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: HarmBlockThreshold.BLOCK_NONE,
156
+ HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_NONE,
157
+ HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_NONE,
158
+ HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: HarmBlockThreshold.BLOCK_NONE
159
+ },
160
  )
161
  llm_response = llm.invoke(new_messages)
162
  print(llm_response)
 
172
 
173
  @app.post("/invoke_model")
174
  def story(prompt: Invoke):
175
+ return inference_model(system_messsage=prompt.system_prompt, prompt=prompt.message)
176
+
177
  @app.post("/generate_level")
178
  def placement(input: Rooms):
179
  print(input)
180
+ markdown_map = generate_map_markdown(input)
181
  print(markdown_map)
182
+ answer = {
183
+ "key": "value"
184
  }
185
  return answer
186
 
187
+ # Dummy function for now
188
+ def determine_vocie_from_npc(npc, genre):
189
  if npc in main_npcs:
190
  return main_npcs[npc]
191
  else:
192
+ if genre == "Male":
193
+ return "./voices/default_male.mp3"
194
+ if genre == "Female":
195
+ return "./voices/default_female.mp3"
196
  else:
197
  return "./voices/narator_out.wav"
198
+
199
+ # Dummy function for now
200
+ def determine_elevenLav_voice_from_npc(npc, genre):
201
  if npc in main_npcs_elevenlabs:
202
  return main_npcs_elevenlabs[npc]
203
  else:
204
+ if genre == "Male":
205
+ return "bIHbv24MWmeRgasZH58o"
206
+ if genre == "Female":
207
+ return "pFZP5JQG7iQjIQuC4Bku"
208
  else:
209
+ return "TX3LPaxmHKxFdv7VOQHJ"
210
 
211
+ @app.post("/generate_wav", response_class=StreamingResponse)
212
  async def generate_wav(message: VoiceMessage):
213
+ try:
214
+ voice = determine_vocie_from_npc(message.npc, message.genre)
215
+ audio_file_pth = handle_file(voice)
216
+
217
  # Generator function to yield audio chunks
218
+ async def audio_stream():
219
+ result = tts_client.predict(
220
+ prompt=message.input,
221
+ language=message.language,
222
+ audio_file_pth=audio_file_pth,
223
+ mic_file_path=None,
224
+ use_mic=False,
225
+ voice_cleanup=False,
226
+ no_lang_auto_detect=False,
227
+ agree=True,
228
+ api_name="/predict"
229
+ )
230
+ for sampling_rate, audio_chunk in result:
231
+ yield audio_chunk.tobytes()
232
+ await asyncio.sleep(0) # Yield control to the event loop
233
 
234
  # Return the generated audio as a streaming response
235
+ return StreamingResponse(audio_stream(), media_type="audio/wav")
 
 
 
 
236
 
237
+ except Exception as e:
238
+ raise HTTPException(status_code=500, detail=str(e))
239
 
240
  @app.get("/generate_voice_eleven", response_class=StreamingResponse)
241
  @app.post("/generate_voice_eleven", response_class=StreamingResponse)
 
247
  Last_message = message
248
 
249
  def audio_stream():
250
+ this_voice_id = determine_elevenLav_voice_from_npc(message.npc, message.genre)
251
+
252
  # Generate the audio stream from ElevenLabs
253
  for chunk in Eleven_client.generate(text=message.input,
254
  voice=Voice(
 
259
  yield chunk
260
 
261
  return StreamingResponse(audio_stream(), media_type="audio/mpeg")
262
+
263
+ # @app.get("/generate_voice_coqui", response_class=StreamingResponse)
264
+ # @app.post("/generate_voice_coqui", response_class=StreamingResponse)
265
+ # def generate_voice_coqui(message: VoiceMessage = None):
266
+ # global Last_message
267
+ # if message is None:
268
+ # message = Last_message
269
+ # else:
270
+ # Last_message = message
271
  #
272
+ # def audio_stream():
273
+ # voice = determine_vocie_from_npc(message.npc, message.genre)
274
+ # result = predict(
275
+ # prompt=message.input,
276
+ # language=message.language,
277
+ # audio_file_pth=voice,
278
+ # mic_file_path=None,
279
+ # use_mic=False,
280
+ # voice_cleanup=False,
281
+ # no_lang_auto_detect=False,
282
+ # agree=True,
283
+ # )
284
+ # # Generate the audio stream from ElevenLabs
285
+ # for chunk in result:
286
+ # print("received : ",chunk)
287
+ # yield chunk
288
  #
289
+ # return StreamingResponse(audio_stream(), media_type="audio/mpeg")
290
+
291
  @app.get("/generate_song")
292
  async def generate_song():
293
+ text = """You are a bard in a video game singing the tales of a little girl in red hood."""
294
 
295
+ song_lyrics = generate_lyrics({
296
  "prompt": f"{text}",
297
+ })
298
  data = custom_generate_audio({
299
  "prompt": song_lyrics['text'],
300
  "tags": "male bard",
301
+ "title": "Everchangin_Quest_song",
302
+ "wait_audio": True,
 
303
  })
304
+ infos = get_audio_information(f"{data[0]['id']},{data[1]['id']}")
305
  return infos
306
 
307
+ # @app.post('/generate_image')
308
+ # def Imagen(image: ImageGen = None):
309
+ # pil_image = generate_image(image.prompt)
 
310
  #
311
+ # # Convert the PIL Image to bytes
312
+ # img_byte_arr = BytesIO()
313
+ # pil_image.save(img_byte_arr, format='PNG')
314
+ # img_byte_arr = img_byte_arr.getvalue()
315
  #
316
+ # # Return the image as a PNG response
317
+ # return Response(content=img_byte_arr, media_type="image/png")
318
 
319
  def generate_map_markdown(data):
320
  import numpy as np
321
+
322
  # Define the room structure with walls and markers
323
  def create_room(room_char):
324
  return [
 
326
  f"β•‘ {room_char} β•‘",
327
  f"β•šβ•β•β•β•"
328
  ]
329
+
330
  # Extract rooms and rooms of interest
331
  rooms = [eval(room) for room in data["rooms"]]
332
  rooms_of_interest = [eval(room) for room in data["room_of_interest"]]
333
+
334
  # Determine grid size
335
  min_x = min(room[0] for room in rooms)
336
  max_x = max(room[0] for room in rooms)
337
  min_y = min(room[1] for room in rooms)
338
  max_y = max(room[1] for room in rooms)
339
+
340
  # Create grid with empty spaces represented by a room-like structure
341
  map_height = (max_y - min_y + 1) * 3
342
  map_width = (max_x - min_x + 1) * 5
343
  grid = np.full((map_height, map_width), " ")
344
+
345
  # Populate grid with rooms and their characteristics
346
  for i, room in enumerate(rooms):
347
  x, y = room
 
356
  room_structure = create_room(room_char)
357
  for j, row in enumerate(room_structure):
358
  grid[y_offset + j, x_offset:x_offset + 5] = list(row)
359
+
360
  # Convert grid to a string format suitable for display
361
  markdown_map = "\n".join("".join(row) for row in grid)
362
+
363
  # Return the map wrapped in triple backticks for proper display in markdown
364
  return f"```\n{markdown_map}\n```"