Yienvee commited on
Commit
f7ef6ab
·
1 Parent(s): 05ee1f9

adding uv and fixing dependencies for hf spaces

Browse files
.gitignore CHANGED
@@ -1,6 +1,9 @@
1
  .venv/
2
  .vscode/
3
- __pycache_/
4
  /models
5
  .env
6
- /Data/Audios
 
 
 
 
1
  .venv/
2
  .vscode/
3
+ __pycache__/
4
  /models
5
  .env
6
+ /Data/Audios
7
+ *.png
8
+ /Data/Rules
9
+ /legacy
.python-version ADDED
@@ -0,0 +1 @@
 
 
1
+ 3.12
Data/Ekalia/Ekalia.png DELETED

Git LFS Details

  • SHA256: 1f53063a640a0f77c66a2bb08f2783603f082f16e7b2dca6f18684cbda6ae2f6
  • Pointer size: 133 Bytes
  • Size of remote file: 35.2 MB
Data/Rules/D&D Livro do jogador.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:2f1bd4f41113f5a13f811ea701d64bd5ed5b02cfadd05c43dbbc9665ec43d7d8
3
- size 23685308
 
 
 
 
Data/Rules/Guia do Mestre D&D 5E.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:280fd8568d793ae8e6dc6de69c17cc8e30963eb3c5e745e3b414c2a249ff85a6
3
- size 21246717
 
 
 
 
README.md CHANGED
@@ -4,7 +4,7 @@ emoji: 🎲
4
  colorFrom: purple
5
  colorTo: blue
6
  sdk: gradio
7
- sdk_version: "4.44.0"
8
  app_file: app.py
9
  pinned: false
10
  ---
 
4
  colorFrom: purple
5
  colorTo: blue
6
  sdk: gradio
7
+ sdk_version: "5.0.0"
8
  app_file: app.py
9
  pinned: false
10
  ---
legacy/src/brain.py DELETED
@@ -1,230 +0,0 @@
1
- """
2
- WorkFlow:
3
-
4
- Pre. O usuário insere a campanha ativa,
5
- (a campanha tem todos os jogadores, posição final deles e oque aconteceu)
6
-
7
- 1. O usuario insere um input para o Cerebro
8
- 2. O input é enviado para o Cerebro (Ollama)
9
- 3. O Cerebro entende o input
10
-
11
- 4. Pega os dados em embedding
12
- 4.1 Do mundo (Ekalia)
13
- 4.2 Pega os dados da campanha ativa atual
14
- 4.3 Pega os dados das regras
15
-
16
- 5. O Cerebro cria um output com base no input e nos dados em embedding
17
- 6. O output é enviado para o usuário
18
-
19
- -Ideias:
20
- Gerador de NPCs
21
- Gerador de missões
22
- Salvar progresso da campanha, junto de logs do jogo, completando com um resumo do que aconteceu
23
-
24
-
25
- """
26
-
27
- from utils.api_key import API_KEY
28
-
29
- from langchain_openai import ChatOpenAI
30
- from langchain_openai import OpenAIEmbeddings
31
-
32
-
33
-
34
- class RAG():
35
- def __init__(self):
36
- pass
37
-
38
- def transcribe_audio_to_text(audio_path: str) -> str:
39
- """
40
- Transcreve um arquivo de áudio para texto usando Whisper.
41
-
42
- Args:
43
- audio_path: O caminho para o arquivo de áudio.
44
-
45
- Returns:
46
- A transcrição do áudio como uma string.
47
- """
48
- import whisper
49
-
50
- model = whisper.load_model("large")
51
- result = model.transcribe(audio_path)
52
- return result["text"]
53
-
54
- def summarize_session_text(session_text: str) -> str:
55
- """
56
- Resume o texto da sessão usando um modelo LLM.
57
-
58
- Args:
59
- session_text: O texto completo da sessão.
60
-
61
- Returns:
62
- Um resumo do texto da sessão.
63
- """
64
-
65
-
66
- from openai import OpenAI
67
- client = OpenAI(api_key = )
68
-
69
- response = client.responses.create(
70
- model="gpt-5.2",
71
- input="Write a one-sentence bedtime story about a unicorn."
72
- )
73
-
74
- print(response.output_text)
75
- return response.output_text
76
-
77
-
78
-
79
- def run_openai():
80
-
81
- # Model
82
- llm = ChatOpenAI(
83
- model="gpt-3.5-turbo",
84
- temperature=1.0, # Aumenta a criatividade e reduz filtros
85
- top_p=0.95, # Aumenta a diversidade de respostas
86
- max_tokens=2048,
87
- api_key=API_KEY,
88
- )
89
-
90
- return llm
91
-
92
-
93
-
94
- def run_local():
95
- # WIP: VLLM Local
96
- ###############################################
97
-
98
- from langchain_openai import ChatOpenAI
99
- from langchain_openai import OpenAIEmbeddings
100
-
101
- llm = ChatOpenAI(
102
- model="model/qwen25-7b-awq",
103
- base_url="http://localhost:8000/v1", #Aqui usa VLLM local
104
- api_key="none"
105
- )
106
-
107
- #################################################
108
-
109
- return llm
110
-
111
- def choose_method(method):
112
- if method == 1:
113
- run_openai()
114
- elif method == 2:
115
- run_local()
116
-
117
- return None
118
-
119
-
120
-
121
-
122
-
123
-
124
- def load_db():
125
- # Vector Store Load
126
- embeddings = OpenAIEmbeddings(
127
- model="text-embedding-3-large",
128
- api_key=API_KEY
129
- )
130
- from langchain_community.vectorstores import FAISS
131
- vectorstore = FAISS.load_local(
132
- "Data/db/ekalia_vector_db",
133
- embeddings,
134
- allow_dangerous_deserialization=True
135
- )
136
-
137
- retriever = vectorstore.as_retriever(
138
- search_kwargs={"k": 5}
139
- )
140
-
141
-
142
-
143
-
144
-
145
-
146
- from langchain.agents import create_tool_calling_agent, AgentExecutor
147
- from langchain.agents import create_agent
148
- from langchain_core.prompts import ChatPromptTemplate
149
-
150
-
151
- prompt = ChatPromptTemplate.from_messages([
152
- (
153
- "system",
154
- """
155
- Você é o Cronista Oficial do mundo de Ekalia.
156
- Use APENAS informações retornadas pelas ferramentas.
157
- Se algo não existir no lore, diga que não está registrado.
158
- """
159
- ),
160
- ("human", "{input}"),
161
- ("placeholder", "{agent_scratchpad}")
162
- ])
163
-
164
-
165
-
166
-
167
- from langchain_core.messages import SystemMessage
168
- from langchain_core.messages import (
169
- SystemMessage,
170
- HumanMessage,
171
- AIMessage
172
- )
173
-
174
- chat_history = [
175
- SystemMessage(
176
- content="Você é um assistente para jogos de RPG de mesa, expert em Dungeons and Dragons 5ª Edição. "
177
- )
178
- ]
179
-
180
-
181
-
182
- ###############
183
-
184
- def main():
185
- method = int(input("Escolha o método de execução (1 para OpenAI, 2 para Local): "))
186
- llm = choose_method(method)
187
- load_db()
188
-
189
- chat_history = []
190
-
191
- agent = create_tool_calling_agent(
192
- llm=llm,
193
- tools=[],
194
- prompt=prompt
195
- )
196
-
197
- agent_executor = AgentExecutor(
198
- agent=agent,
199
- tools=[],
200
- verbose=True
201
- )
202
-
203
-
204
- while True:
205
- message = input("\nDigite uma mensagem:\n")
206
-
207
- if message.lower() in ["sair", "exit", "quit"]:
208
- break
209
-
210
- message = [*chat_history, HumanMessage(content=message)]
211
-
212
- result = agent_executor.invoke({"messages": message})
213
- print(result)
214
-
215
-
216
- """start_time = time.time()
217
- word = ""
218
-
219
-
220
-
221
- while word != "quit":
222
- word = input("Digite uma palavra (ou 'quit' para sair): ")
223
- if word != "quit":
224
- resp = llm.invoke(word)
225
- end_time = time.time()
226
- elapsed = end_time - start_time
227
- print(resp)
228
- print(f"Tempo de resposta: {elapsed:.2f} segundos")
229
- else:
230
- print("Quitting")"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
legacy/src/db.py DELETED
@@ -1,41 +0,0 @@
1
- from utils.get_data import get_data
2
- from utils.api_key import API_KEY
3
-
4
-
5
- from langchain_openai import OpenAIEmbeddings
6
- from langchain_text_splitters import RecursiveCharacterTextSplitter
7
-
8
-
9
- from langchain_community.docstore.in_memory import InMemoryDocstore
10
- from langchain_community.vectorstores import FAISS
11
-
12
-
13
- import faiss
14
-
15
-
16
- data = get_data(verbose=False)
17
-
18
-
19
- text_splitter = RecursiveCharacterTextSplitter(
20
- chunk_size=800,
21
- chunk_overlap=120,
22
- separators=["\n\n", "\n", ".", " "]
23
- )
24
-
25
-
26
- docs_split = text_splitter.split_documents(data)
27
-
28
-
29
- embeddings = OpenAIEmbeddings(
30
- model="text-embedding-3-large",
31
- api_key=API_KEY
32
- )
33
-
34
-
35
- vectorstore = FAISS.from_documents(
36
- documents=docs_split,
37
- embedding=embeddings
38
- )
39
-
40
-
41
- vectorstore.save_local("Data/db/ekalia_vector_db")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
legacy/src/ears/__pycache__/whisper.cpython-312.pyc DELETED
Binary file (1.36 kB)
 
legacy/src/ears/whisper.py DELETED
@@ -1,5 +0,0 @@
1
-
2
-
3
- LLM_MODEL = "deepseek-r1:latest" # ou "llama3"
4
- # da pra trocar pelo modelo local usando vllm
5
-
 
 
 
 
 
 
legacy/src/front_meta.py DELETED
@@ -1,129 +0,0 @@
1
- import sys
2
-
3
- from PyQt6.QtCore import QSize, Qt
4
- from PyQt6.QtWidgets import QApplication, QMainWindow, QLabel, QLineEdit, QGridLayout, QWidget, QPushButton
5
-
6
- """
7
-
8
- Menus - Inicial botoes para -> Durante a sessão,
9
-
10
-
11
-
12
- """
13
-
14
-
15
-
16
-
17
- WINDOW_TITLES = [
18
- "My App",
19
- "Generative AI Assistant",
20
- "Post Session Helper",
21
- ]
22
-
23
-
24
-
25
- # Subclass QMainWindow to customize your application's main window
26
- class MainWindow(QMainWindow):
27
- def __init__(self):
28
- super().__init__()
29
- self.setMinimumSize(QSize(800, 600))
30
- self.STATES = ["main_menu", "generate", "session_helper"]
31
- self.cur_state = "main_menu"
32
- self.MENU_STATE(self.cur_state)
33
-
34
- def MENU_STATE(self, state):
35
- self.setWindowTitle(WINDOW_TITLES[self.STATES.index(state)])
36
- if state == self.STATES[0]:
37
- self.MAIN_MENU()
38
- elif state == self.STATES[1]:
39
- self.GEN_MENU()
40
- elif state == self.STATES[2]:
41
- self.SESSION_HELPER_MENU()
42
-
43
-
44
-
45
- def MAIN_MENU(self):
46
- # Clear the screen if needed
47
- if self.centralWidget():
48
- for widget in self.centralWidget().children():
49
- widget.deleteLater()
50
-
51
- self.GenButton = QPushButton("Generate")
52
- self.SHButton = QPushButton("Session Helper")
53
-
54
- self.GenButton.clicked.connect(lambda: self.MENU_STATE("generate"))
55
- self.SHButton.clicked.connect(lambda: self.MENU_STATE("session_helper"))
56
-
57
- layout = QGridLayout()
58
- layout.addWidget(self.GenButton, 0, 0, Qt.AlignmentFlag.AlignCenter)
59
- layout.addWidget(self.SHButton, 0, 1, Qt.AlignmentFlag.AlignCenter)
60
-
61
- container = QWidget()
62
- container.setLayout(layout)
63
- self.setCentralWidget(container)
64
-
65
-
66
-
67
-
68
- def GEN_MENU(self):
69
- # Clear the screen
70
- if self.centralWidget():
71
- for widget in self.centralWidget().children():
72
- widget.deleteLater()
73
-
74
- layout = QGridLayout()
75
-
76
-
77
- label = QLabel("Generate Menu")
78
- layout.addWidget(label, 0, 0, Qt.AlignmentFlag.AlignCenter)
79
- ###########################################################
80
-
81
-
82
-
83
-
84
- ############################################################
85
-
86
- backButton = QPushButton("Back to Main Menu")
87
- backButton.clicked.connect(lambda: self.MENU_STATE("main_menu"))
88
- layout.addWidget(backButton, 3, 0, Qt.AlignmentFlag.AlignCenter)
89
-
90
- container = QWidget()
91
- container.setLayout(layout)
92
- self.setCentralWidget(container)
93
-
94
- def SESSION_HELPER_MENU(self):
95
- # Clear the screen
96
- if self.centralWidget():
97
- for widget in self.centralWidget().children():
98
- widget.deleteLater()
99
-
100
- layout = QGridLayout()
101
-
102
- label = QLabel("Session Helper Menu")
103
- layout.addWidget(label, 0, 0, Qt.AlignmentFlag.AlignCenter)
104
- ###########################################################
105
-
106
-
107
-
108
- ###########################################################
109
-
110
- backButton = QPushButton("Back to Main Menu")
111
- backButton.clicked.connect(lambda: self.MENU_STATE("main_menu"))
112
- layout.addWidget(backButton, 3, 0, Qt.AlignmentFlag.AlignCenter)
113
-
114
- container = QWidget()
115
- container.setLayout(layout)
116
- self.setCentralWidget(container)
117
-
118
-
119
- container = QWidget()
120
- container.setLayout(layout)
121
- self.setCentralWidget(container)
122
-
123
-
124
- app = QApplication(sys.argv)
125
-
126
- window = MainWindow()
127
- window.show()
128
-
129
- app.exec()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
legacy/src/gen/__init__.py DELETED
File without changes
legacy/src/gen/__pycache__/npc_gen.cpython-312.pyc DELETED
Binary file (446 Bytes)
 
legacy/src/gen/npc_gen.py DELETED
@@ -1,101 +0,0 @@
1
- # Aqui pegaremos o contexto da campanha e local do NPC
2
- import random
3
-
4
- races = {
5
- "human": {"str": 1, "dex": 1, "con": 1, "int": 1, "wis": 1, "cha": 1},
6
-
7
- "elf": {"str": 0, "dex": 2, "con": 0, "int": 0, "wis": 0, "cha": 0},
8
- "high_elf": {"str": 0, "dex": 2, "con": 0, "int": 1, "wis": 0, "cha": 0},
9
- "wood_elf": {"str": 0, "dex": 2, "con": 0, "int": 0, "wis": 1, "cha": 0},
10
- "dark_elf": {"str": 0, "dex": 2, "con": 0, "int": 0, "wis": 0, "cha": 1},
11
-
12
- "dwarf": {"str": 0, "dex": 0, "con": 2, "int": 0, "wis": 0, "cha": 0},
13
- "hill_dwarf": {"str": 0, "dex": 0, "con": 2, "int": 0, "wis": 1, "cha": 0},
14
- "mountain_dwarf": {"str": 2, "dex": 0, "con": 2, "int": 0, "wis": 0, "cha": 0},
15
-
16
- "halfling": {"str": 0, "dex": 2, "con": 0, "int": 0, "wis": 0, "cha": 0},
17
- "lightfoot_halfling": {"str": 0, "dex": 2, "con": 0, "int": 0, "wis": 0, "cha": 1},
18
- "stout_halfling": {"str": 0, "dex": 2, "con": 1, "int": 0, "wis": 0, "cha": 0},
19
-
20
- "dragonborn": {"str": 2, "dex": 0, "con": 0, "int": 0, "wis": 0, "cha": 1},
21
- "gnome": {"str": 0, "dex": 0, "con": 0, "int": 2, "wis": 0, "cha": 0},
22
- "forest_gnome": {"str": 0, "dex": 1, "con": 0, "int": 2, "wis": 0, "cha": 0},
23
- "rock_gnome": {"str": 0, "dex": 0, "con": 1, "int": 2, "wis": 0, "cha": 0},
24
-
25
- "half_elf": {"str": 0, "dex": 0, "con": 0, "int": 0, "wis": 0, "cha": 2},
26
- "half_orc": {"str": 2, "dex": 0, "con": 1, "int": 0, "wis": 0, "cha": 0},
27
-
28
- "tiefling": {"str": 0, "dex": 0, "con": 0, "int": 1, "wis": 0, "cha": 2}
29
- }
30
-
31
- class Race:
32
- def __init__(self, name, base_bonus, subraces=None):
33
- self.name = name
34
- self.base_bonus = base_bonus
35
- self.subraces = subraces or {}
36
-
37
- def get_bonus(self, subrace=None):
38
- bonus = self.base_bonus.copy()
39
- if subrace and subrace in self.subraces:
40
- for stat, value in self.subraces[subrace].items():
41
- bonus[stat] = bonus.get(stat, 0) + value
42
- return bonus
43
-
44
- class NPC():
45
- def __init__(self):
46
- self.str
47
- self.dex
48
- self.con
49
- self.int
50
- self.wis
51
- self.char
52
-
53
- self.race
54
- self.stats = self.roll_stats
55
-
56
- def roll_stats(self):
57
- stats = []
58
- for _ in range(6):
59
- rolls = []
60
- for _ in range(4):
61
- rolls.append(random.randint(1, 6))
62
- stat = max(sum(rolls) - min(rolls), 8)
63
- print(stat)
64
- stats.append(stat)
65
-
66
-
67
- stats.sort(reverse=True)
68
-
69
- return stats
70
-
71
- def roll_race(self, context):
72
- """
73
- Ferramar
74
- - Humanos
75
- - Draconatos
76
- - Aasimar (militares)
77
- Ressamar
78
- - Humanos
79
- - Tritões (minorias costeiras)
80
- - Tabaxi
81
-
82
-
83
-
84
- """
85
- pass
86
-
87
-
88
- class Combative_NPC(NPC):
89
- def __init__(self):
90
-
91
- self.classe
92
-
93
- def roll_class(self):
94
- pass
95
-
96
- def background():
97
- NotImplemented
98
-
99
- class Non_Combative_NPC(NPC):
100
- def __init__(self):
101
- pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
legacy/src/gen/side_quest_gen.py DELETED
File without changes
legacy/src/main.py DELETED
@@ -1,134 +0,0 @@
1
- import os
2
- import json
3
- import ears.whisper as whisper
4
-
5
- """
6
- # TODO:
7
- 1. Trocar Tkinter por pyside6
8
-
9
- """
10
-
11
-
12
- import tkinter as tk
13
- from tkinter import filedialog, messagebox
14
-
15
-
16
- OUTPUT_IMAGE_DIR = "output_images"
17
-
18
-
19
- class sessionHelper():
20
- def __init__(self, root ):
21
-
22
- self.root = root
23
-
24
- self.root.geometry("600x400")
25
- self.root.title("RPG Session Helper")
26
-
27
- self.campaings = self.get_all_campaings()
28
- self.main_menu()
29
-
30
-
31
- # Pega os dados das campanhas: Jogadores, Numero de sessoes, Logs
32
- def get_all_campaings(self):
33
- # Placeholder: Retorna uma lista de campanhas
34
- with open(os.path.join("Data", "Campaings", "campaings.json"), "r") as file:
35
- return json.load(file)
36
- return
37
-
38
- def add_or_remove_player_to_campaing(self, campaing_id, player_data):
39
- # Placeholder: Adiciona um jogador a uma campanha específica
40
- return
41
-
42
- def main_menu(self):
43
-
44
- b1 = tk.Button(self.root, text = "Gerar Algo", command=self.GENERATE_MENU)
45
- b1.pack(pady=10)
46
-
47
- b2 = tk.Button(self.root, text="Gerenciar Campanhas", command=self.SELECT_CAMPAING_MENU)
48
- b2.pack(pady=10)
49
-
50
-
51
-
52
-
53
- def GENERATE_MENU(self):
54
- pass
55
- # Menu principal
56
- def SELECT_CAMPAING_MENU(self):
57
-
58
- # Clear the screen
59
- for widget in self.root.winfo_children():
60
- widget.destroy()
61
-
62
- title = tk.Label(self.root, text="Campanhas Ativas", font=("Arial", 16, "bold"))
63
- title.pack(pady=10)
64
-
65
- # Lista de campanhas
66
- self.campaign_list = tk.Listbox(self.root, height=8, width=50)
67
- self.campaign_list.pack(pady=10)
68
- for c in self.campaings:
69
- self.campaign_list.insert(tk.END, f"{c['id']} - {c['name']}")
70
-
71
- select_btn = tk.Button(self.root, text="Selecionar Campanha", command=self.select_campaign)
72
- select_btn.pack(pady=5)
73
-
74
- self.players_label = tk.Label(self.root, text="", font=("Arial", 12))
75
- self.players_label.pack(pady=10)
76
-
77
- self.transcribe_btn = tk.Button(self.root, text="Transcrever e Resumir Sessão", command=self.transcribe_and_summarize)
78
- self.transcribe_btn.pack(pady=10)
79
- self.transcribe_btn.config(state=tk.DISABLED)
80
-
81
- def select_campaign(self):
82
- selection = self.campaign_list.curselection()
83
- if not selection:
84
- messagebox.showwarning("Aviso", "Selecione uma campanha primeiro.")
85
- return
86
-
87
- index = selection[0]
88
- self.selected_campaign = self.campaings[index]
89
- players_text = "Jogadores:\n" + "\n".join(
90
- [f"- {p['Nome']} ({p['Raça']} {p['Classe']})" for p in self.selected_campaign.get("players", [])]
91
- )
92
- self.players_label.config(text=players_text)
93
- self.transcribe_btn.config(state=tk.NORMAL)
94
-
95
- def log_session(self, campaing_id, session_number, session_data):
96
- # Placeholder: Loga os dados de uma sessão para uma campanha específica
97
- return
98
-
99
- def transcribe_and_summarize(self):
100
-
101
-
102
- audio_path = filedialog.askopenfilename(title="Selecione o arquivo de áudio da sessão")
103
- if not audio_path:
104
- return
105
-
106
- try:
107
- session_text = whisper.transcribe_audio_to_text(audio_path)
108
- summary = whisper.summarize_session_text(session_text)
109
- messagebox.showinfo("Resumo da Sessão", summary)
110
- except Exception as e:
111
- messagebox.showerror("Erro", f"Ocorreu um erro: {str(e)}")
112
-
113
-
114
-
115
- if __name__ == "__main__":
116
- import tkinter as tk
117
- from tkinter import simpledialog
118
-
119
- # Adicionar Menu principal interativo com TKinter
120
- # - Listar campanhas
121
- # - Adicionar/Remover jogadores da campanha
122
- # - Selecionar campanha -> Logar sessão
123
- #
124
- # - Ver resumo da campanha
125
-
126
- root = tk.Tk()
127
- sh = sessionHelper(root)
128
- root.mainloop()
129
- # Listar campanhas disponíveis
130
- for campaing in sh.campaings:
131
- print(f"ID: {campaing['id']}, Nome: {campaing['name']}")
132
- # Selecionar campanha
133
-
134
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
legacy/src/pdf_reader/pdf_agent.py DELETED
@@ -1,92 +0,0 @@
1
- import fitz # PyMuPDF
2
- import io
3
- from PIL import Image
4
- import os
5
-
6
- # --- Configuração ---
7
- # Crie uma pasta para salvar as imagens extraídas
8
- OUTPUT_IMAGE_DIR = "extracted_images"
9
- if not os.path.exists(OUTPUT_IMAGE_DIR):
10
- os.makedirs(OUTPUT_IMAGE_DIR)
11
-
12
-
13
- def get_image_description(image_bytes: bytes) -> str:
14
- """
15
- Esta é a função que se comunicará com um modelo de visão.
16
- Por enquanto, ela apenas retorna um placeholder.
17
- """
18
- # TODO: Implementar a chamada para a API de visão (ex: OpenAI GPT-4o)
19
- # from openai import OpenAI
20
- # client = OpenAI(api_key="SUA_CHAVE_API")
21
- # ... chamada da API ...
22
- return "[Descrição da imagem pendente]"
23
-
24
- def process_pdf(pdf_path: str) -> str:
25
- """
26
- Processa um único arquivo PDF, extraindo texto e descrevendo imagens.
27
-
28
- Args:
29
- pdf_path: O caminho para o arquivo PDF.
30
-
31
- Returns:
32
- Uma string contendo todo o texto consolidado do PDF.
33
- """
34
- print(f"Processando PDF: {pdf_path}...")
35
- doc = fitz.open(pdf_path)
36
- consolidated_text = ""
37
-
38
- for page_num, page in enumerate(doc):
39
- # 1. Extrair texto da página
40
- consolidated_text += f"--- Página {page_num + 1} ---\n"
41
- consolidated_text += page.get_text()
42
- consolidated_text += "\n"
43
-
44
- # 2. Extrair imagens da página
45
- image_list = page.get_images(full=True)
46
- if image_list:
47
- consolidated_text += f"\n[IMAGENS ENCONTRADAS NA PÁGINA {page_num + 1}]\n"
48
-
49
- for img_index, img in enumerate(image_list):
50
- xref = img[0]
51
- base_image = doc.extract_image(xref)
52
- image_bytes = base_image["image"]
53
-
54
- # Obter descrição da imagem (atualmente um placeholder)
55
- description = get_image_description(image_bytes)
56
-
57
- consolidated_text += f"- Imagem {img_index + 1}: {description}\n"
58
-
59
- # Opcional: Salvar a imagem em disco para verificação
60
- image_ext = base_image["ext"]
61
- image_filename = f"{os.path.basename(pdf_path)}_p{page_num+1}_img{img_index+1}.{image_ext}"
62
- image_path = os.path.join(OUTPUT_IMAGE_DIR, image_filename)
63
- with open(image_path, "wb") as img_file:
64
- img_file.write(image_bytes)
65
- # print(f" - Imagem salva em: {image_path}")
66
-
67
- doc.close()
68
- print("Processamento concluído.")
69
- return consolidated_text
70
-
71
- # --- Exemplo de Uso ---
72
- if __name__ == "__main__":
73
- # Encontre um PDF no seu workspace para testar
74
- # Vou usar um que vi na sua estrutura de arquivos.
75
- # Adapte o caminho se necessário.
76
- test_pdf_path = "DH.pdf"
77
-
78
- if os.path.exists(test_pdf_path):
79
- full_text_content = process_pdf(test_pdf_path)
80
-
81
- # Salva o resultado em um arquivo de texto para análise
82
- output_txt_filename = f"{os.path.basename(test_pdf_path)}.txt"
83
- with open(output_txt_filename, "w", encoding="utf-8") as f:
84
- f.write(full_text_content)
85
-
86
- print(f"\nConteúdo extraído e salvo em '{output_txt_filename}'")
87
- # print("\n--- CONTEÚDO EXTRAÍDO ---")
88
- # print(full_text_content)
89
- else:
90
- print(f"Arquivo de teste não encontrado em: {test_pdf_path}")
91
- print("Por favor, ajuste a variável 'test_pdf_path' no final do script para um PDF existente.")
92
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
legacy/src/session_resume.py DELETED
@@ -1,75 +0,0 @@
1
- import whisper
2
- import openai
3
- from utils.api_key import PYANNOTE_API_KEY
4
-
5
-
6
- LLM_MODEL = "deepseek-r1:latest" # ou "llama3"
7
- # da pra trocar pelo modelo local usando vllm
8
-
9
- def assign_speaker(segment, diarization):
10
- for turn, _, speaker in diarization.itertracks(yield_label=True):
11
- if turn.start <= segment["start"] <= turn.end:
12
- return speaker
13
- return "Unknown"
14
-
15
-
16
- def transcribe_audio_to_text(audio_path: str) -> str:
17
- """
18
- Transcreve um arquivo de áudio para texto usando Whisper.
19
-
20
- Args:
21
- audio_path: O caminho para o arquivo de áudio.
22
-
23
- Returns:
24
- A transcrição do áudio como uma string.
25
- """
26
-
27
-
28
- model = whisper.load_model("large", device="cuda")
29
- result = model.transcribe(audio_path,verbose=True)
30
-
31
- segments = result["segments"]
32
-
33
- from pyannote.audio import Pipeline
34
-
35
- pipeline = Pipeline.from_pretrained(
36
- "pyannote/speaker-diarization",
37
- use_auth_token=PYANNOTE_API_KEY
38
- )
39
-
40
- diarization = pipeline(audio_path)
41
-
42
-
43
- for seg in segments:
44
- speaker = assign_speaker(seg, diarization)
45
- print(f"{speaker}: {seg['text']}")
46
-
47
- print(result)
48
- return segments
49
-
50
- def summarize_session_text(session_text: str) -> str:
51
- """
52
- Resume o texto da sessão usando um modelo LLM.
53
-
54
- Args:
55
- session_text: O texto completo da sessão.
56
-
57
- Returns:
58
- Um resumo do texto da sessão.
59
- """
60
- from langchain_ollama import OllamaLLM
61
-
62
- llm = OllamaLLM(
63
- model=LLM_MODEL, # ou "llama3"
64
- temperature=1.0, # Aumenta a criatividade e reduz filtros
65
- top_p=0.95, # Aumenta a diversidade de respostas
66
- top_k=40, # Permite mais tokens candidatos
67
- num_ctx=4096 # Contexto maior
68
- )
69
- prompt = f"Resuma oque aconteceu na seguinte sessão de RPG:\n\n{session_text}\n\nResumo:"
70
- summary = llm.invoke(prompt)
71
- return summary
72
-
73
-
74
-
75
- transcribe_audio_to_text("Data/Audios/c4e1.mp4")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
legacy/src/testes.ipynb DELETED
@@ -1,405 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "code",
5
- "execution_count": 26,
6
- "id": "cfad16e7",
7
- "metadata": {},
8
- "outputs": [
9
- {
10
- "name": "stdout",
11
- "output_type": "stream",
12
- "text": [
13
- "Read file: Lore/Guilds/Formulario de Inscrição.txt with content length: 816\n",
14
- "Read file: Lore/Historia/As cores.txt with content length: 170\n",
15
- "Read file: Lore/Historia/Deuses.txt with content length: 1288\n",
16
- "Read file: Lore/Livros/A traição de Aghamina, por Lord Gamon.txt with content length: 1952\n",
17
- "Read file: Lore/Livros/A lenda dos 7.txt with content length: 2385\n",
18
- "Read file: Lore/Livros/A Heroina Aghamina.txt with content length: 2240\n",
19
- "Read file: Cristais/Cristais.txt with content length: 1150\n",
20
- "Read file: Cristais/Cristais/Afixos.txt with content length: 1264\n",
21
- "Read file: Cristais/Cristais/Cristal de Gelo I/Bolinha de Neve.txt with content length: 1468\n",
22
- "Read file: Cristais/Cristais/Cristal de Gelo I/Coruja.txt with content length: 110\n",
23
- "Read file: Cristais/Cristais/Cristal de Gelo I/Urso polar elemental.txt with content length: 0\n",
24
- "Read file: Cristais/Cristais/Cristal de Gelo I/Baguera, O tigre gelido.txt with content length: 1152\n",
25
- "Read file: Cristais/Cristais/Cristal de Água I/Giff.txt with content length: 47\n",
26
- "Read file: Cristais/Cristais/Cristal de Água I/Jaré.txt with content length: 0\n",
27
- "Read file: Cristais/Cristais/Cristal de Água I/O Patorro.txt with content length: 0\n",
28
- "Read file: Cristais/Cristais/Cristal de Fogo I/Aranha Infernal.txt with content length: 62\n",
29
- "Read file: Cristais/Cristais/Cristal de Fogo I/Filhote de Anjarex.txt with content length: 0\n",
30
- "Read file: Cristais/Cristais/Cristal de Fogo I/Kobold Escudragão.txt with content length: 81\n",
31
- "Read file: Mundo/Linguas.txt with content length: 1404\n",
32
- "Read file: Mundo/Ekalia.txt with content length: 115\n",
33
- "Read file: Mundo/Continentes/Ploya.txt with content length: 272\n",
34
- "Read file: Mundo/Continentes/Amaril.txt with content length: 47\n",
35
- "Read file: Mundo/Continentes/Soléternel.txt with content length: 39\n",
36
- "Read file: Mundo/Continentes/Paises_Ploya/TerraMijada.txt with content length: 0\n",
37
- "Read file: Mundo/Continentes/Paises_Ploya/Costas Piratas/Ressamar.txt with content length: 214\n",
38
- "Read file: Mundo/Continentes/Paises_Ploya/Costas Piratas/Farragemar.txt with content length: 196\n",
39
- "Read file: Mundo/Continentes/Paises_Ploya/Terras Vivas/SilvanVale.txt with content length: 439\n",
40
- "Read file: Mundo/Continentes/Paises_Ploya/Terras Vivas/Furtunasue.txt with content length: 309\n",
41
- "Read file: Mundo/Continentes/Paises_Ploya/Terras Vivas/Steinberg.txt with content length: 587\n",
42
- "Read file: Mundo/Continentes/Paises_Ploya/Terras Vivas/Maraven.txt with content length: 506\n",
43
- "Read file: Mundo/Continentes/Paises_Ploya/Terras Vivas/Matareal.txt with content length: 455\n",
44
- "Read file: Mundo/Continentes/Paises_Ploya/Terra Mijada/Glückslott.txt with content length: 579\n",
45
- "Read file: Mundo/Continentes/Paises_Ploya/Terra Mijada/Andarilhos.txt with content length: 252\n",
46
- "Read file: Mundo/Continentes/Paises_Ploya/Terra Mijada/Fauna.txt with content length: 458\n",
47
- "Read file: Mundo/Continentes/Paises_Ploya/Terra Mijada/Glusckslott/As minas de Glüsckssot.txt with content length: 50\n",
48
- "Read file: Mundo/Continentes/Paises_Ploya/Terra Mijada/Glusckslott/Tavernas/Helle Oase.txt with content length: 2031\n",
49
- "Read file: Mundo/Continentes/Paises_Ploya/Terra Mijada/Glusckslott/Tavernas/Helle Oase (Oasis brilhante).txt with content length: 2037\n",
50
- "Read file: Mundo/Continentes/Paises_Ploya/Terra Mijada/Glusckslott/Tavernas/Wüstenwinde (Ventos do deserto).txt with content length: 1679\n",
51
- "Read file: Mundo/Continentes/Paises_Ploya/Terra Mijada/Glusckslott/Lojas/Mercado principal/Emporio do Solstício (Itens Magicos).txt with content length: 1176\n",
52
- "Read file: Mundo/Continentes/Paises_Ploya/Terra Mijada/Glusckslott/Lojas/Mercado principal/Antiguidades do Deserto(Relíquias).txt with content length: 61\n",
53
- "Read file: Mundo/Guildas/Gelb Skarabäus.txt with content length: 179\n",
54
- "Read file: Mundo/Guildas/Guilda (Gelb Skarabäus)/Escaravelho amarelo.txt with content length: 0\n",
55
- "Read file: Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCs.txt with content length: 0\n",
56
- "Read file: Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Taverneira (Krea).txt with content length: 728\n",
57
- "Read file: Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Krea Hammerhemd.txt with content length: 728\n",
58
- "Read file: Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Guild Master (Atur).txt with content length: 812\n",
59
- "Read file: Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Askad Edelmetall.txt with content length: 758\n",
60
- "Read file: Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Atur Hammerhemd.txt with content length: 0\n",
61
- "Read file: Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Quest G (Askad).txt with content length: 758\n",
62
- "Read file: Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Cozinheira (Thrinan).txt with content length: 900\n",
63
- "Read file: Campanhas/A Cidade Dourada/Sessão 01.txt with content length: 1468\n",
64
- "Read file: Campanhas/A Cidade Dourada/Sessão 02.txt with content length: 144\n",
65
- "Read file: Campanhas/A Cidade Dourada/Sessão 03.txt with content length: 0\n",
66
- "Read file: Campanhas/A Cidade Dourada/NPCs/Zackrias Bluff.txt with content length: 0\n",
67
- "Read file: Campanhas/A Cidade Dourada/Inimigos/Os Meninos.txt with content length: 1296\n",
68
- "Read file: Campanhas/A Cidade Dourada/Inimigos/Ignacio.txt with content length: 86\n"
69
- ]
70
- },
71
- {
72
- "data": {
73
- "text/html": [
74
- "<div>\n",
75
- "<style scoped>\n",
76
- " .dataframe tbody tr th:only-of-type {\n",
77
- " vertical-align: middle;\n",
78
- " }\n",
79
- "\n",
80
- " .dataframe tbody tr th {\n",
81
- " vertical-align: top;\n",
82
- " }\n",
83
- "\n",
84
- " .dataframe thead th {\n",
85
- " text-align: right;\n",
86
- " }\n",
87
- "</style>\n",
88
- "<table border=\"1\" class=\"dataframe\">\n",
89
- " <thead>\n",
90
- " <tr style=\"text-align: right;\">\n",
91
- " <th></th>\n",
92
- " <th>Lore/Guilds/Formulario de Inscrição.txt</th>\n",
93
- " <th>Lore/Historia/As cores.txt</th>\n",
94
- " <th>Lore/Historia/Deuses.txt</th>\n",
95
- " <th>Lore/Livros/A traição de Aghamina, por Lord Gamon.txt</th>\n",
96
- " <th>Lore/Livros/A lenda dos 7.txt</th>\n",
97
- " <th>Lore/Livros/A Heroina Aghamina.txt</th>\n",
98
- " <th>Cristais/Cristais.txt</th>\n",
99
- " <th>Cristais/Cristais/Afixos.txt</th>\n",
100
- " <th>Cristais/Cristais/Cristal de Gelo I/Bolinha de Neve.txt</th>\n",
101
- " <th>Cristais/Cristais/Cristal de Gelo I/Coruja.txt</th>\n",
102
- " <th>...</th>\n",
103
- " <th>Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Askad Edelmetall.txt</th>\n",
104
- " <th>Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Atur Hammerhemd.txt</th>\n",
105
- " <th>Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Quest G (Askad).txt</th>\n",
106
- " <th>Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Cozinheira (Thrinan).txt</th>\n",
107
- " <th>Campanhas/A Cidade Dourada/Sessão 01.txt</th>\n",
108
- " <th>Campanhas/A Cidade Dourada/Sessão 02.txt</th>\n",
109
- " <th>Campanhas/A Cidade Dourada/Sessão 03.txt</th>\n",
110
- " <th>Campanhas/A Cidade Dourada/NPCs/Zackrias Bluff.txt</th>\n",
111
- " <th>Campanhas/A Cidade Dourada/Inimigos/Os Meninos.txt</th>\n",
112
- " <th>Campanhas/A Cidade Dourada/Inimigos/Ignacio.txt</th>\n",
113
- " </tr>\n",
114
- " </thead>\n",
115
- " <tbody>\n",
116
- " <tr>\n",
117
- " <th>file name</th>\n",
118
- " <td>Lore/Guilds/Formulario de Inscrição.txt</td>\n",
119
- " <td>Lore/Historia/As cores.txt</td>\n",
120
- " <td>Lore/Historia/Deuses.txt</td>\n",
121
- " <td>Lore/Livros/A traição de Aghamina, por Lord Ga...</td>\n",
122
- " <td>Lore/Livros/A lenda dos 7.txt</td>\n",
123
- " <td>Lore/Livros/A Heroina Aghamina.txt</td>\n",
124
- " <td>Cristais/Cristais.txt</td>\n",
125
- " <td>Cristais/Cristais/Afixos.txt</td>\n",
126
- " <td>Cristais/Cristais/Cristal de Gelo I/Bolinha de...</td>\n",
127
- " <td>Cristais/Cristais/Cristal de Gelo I/Coruja.txt</td>\n",
128
- " <td>...</td>\n",
129
- " <td>Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Ask...</td>\n",
130
- " <td>Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Atu...</td>\n",
131
- " <td>Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Que...</td>\n",
132
- " <td>Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Coz...</td>\n",
133
- " <td>Campanhas/A Cidade Dourada/Sessão 01.txt</td>\n",
134
- " <td>Campanhas/A Cidade Dourada/Sessão 02.txt</td>\n",
135
- " <td>Campanhas/A Cidade Dourada/Sessão 03.txt</td>\n",
136
- " <td>Campanhas/A Cidade Dourada/NPCs/Zackrias Bluff...</td>\n",
137
- " <td>Campanhas/A Cidade Dourada/Inimigos/Os Meninos...</td>\n",
138
- " <td>Campanhas/A Cidade Dourada/Inimigos/Ignacio.txt</td>\n",
139
- " </tr>\n",
140
- " <tr>\n",
141
- " <th>content</th>\n",
142
- " <td>Nome Completo:\\nIncluir um campo para o nome c...</td>\n",
143
- " <td>Vermelho\\tVida\\t\\tIvo\\nLaranja \\tEnergia\\t\\tEl...</td>\n",
144
- " <td>Janus Brightspark, Rato Guardião, Deus da Enge...</td>\n",
145
- " <td>Anos depois da grande vitória sobre Zeref, Eka...</td>\n",
146
- " <td>Em um mundo distante, no reino de Ekalia, as t...</td>\n",
147
- " <td>Anos após a vitória sobre Zeref, Ekalia vivia ...</td>\n",
148
- " <td># Oque são Cristais?\\n\\nOs Cristais são pedras...</td>\n",
149
- " <td>Afixos\\n\\n\\tMisericordioso\\nEsse inimigo ignor...</td>\n",
150
- " <td>Bolinha de neve (80HP AC 12)\\n\\nAfixos: Miseri...</td>\n",
151
- " <td>Frostaluna (40HP 13AC)\\n\\n\\nAfixos: Misericord...</td>\n",
152
- " <td>...</td>\n",
153
- " <td>Askad Edelmetall\\né uma feiticeira nível 10, a...</td>\n",
154
- " <td></td>\n",
155
- " <td>Askad Edelmetall\\né uma feiticeira nível 10, a...</td>\n",
156
- " <td>Thrinan Kieselstein\\n\\né uma cozinheira anã da...</td>\n",
157
- " <td>Retcon: \\nA viagem dos 4 foi conduzida por um ...</td>\n",
158
- " <td>Recap:\\nNa sessão passada, nossos heróis(?) fo...</td>\n",
159
- " <td></td>\n",
160
- " <td></td>\n",
161
- " <td>Primeiros Boss caso seja no armazem\\n\\n\\nOs Me...</td>\n",
162
- " <td>Primeiro boss caso batalhem na caravana\\n\\n\\n\\...</td>\n",
163
- " </tr>\n",
164
- " </tbody>\n",
165
- "</table>\n",
166
- "<p>2 rows × 56 columns</p>\n",
167
- "</div>"
168
- ],
169
- "text/plain": [
170
- " Lore/Guilds/Formulario de Inscrição.txt \\\n",
171
- "file name Lore/Guilds/Formulario de Inscrição.txt \n",
172
- "content Nome Completo:\\nIncluir um campo para o nome c... \n",
173
- "\n",
174
- " Lore/Historia/As cores.txt \\\n",
175
- "file name Lore/Historia/As cores.txt \n",
176
- "content Vermelho\\tVida\\t\\tIvo\\nLaranja \\tEnergia\\t\\tEl... \n",
177
- "\n",
178
- " Lore/Historia/Deuses.txt \\\n",
179
- "file name Lore/Historia/Deuses.txt \n",
180
- "content Janus Brightspark, Rato Guardião, Deus da Enge... \n",
181
- "\n",
182
- " Lore/Livros/A traição de Aghamina, por Lord Gamon.txt \\\n",
183
- "file name Lore/Livros/A traição de Aghamina, por Lord Ga... \n",
184
- "content Anos depois da grande vitória sobre Zeref, Eka... \n",
185
- "\n",
186
- " Lore/Livros/A lenda dos 7.txt \\\n",
187
- "file name Lore/Livros/A lenda dos 7.txt \n",
188
- "content Em um mundo distante, no reino de Ekalia, as t... \n",
189
- "\n",
190
- " Lore/Livros/A Heroina Aghamina.txt \\\n",
191
- "file name Lore/Livros/A Heroina Aghamina.txt \n",
192
- "content Anos após a vitória sobre Zeref, Ekalia vivia ... \n",
193
- "\n",
194
- " Cristais/Cristais.txt \\\n",
195
- "file name Cristais/Cristais.txt \n",
196
- "content # Oque são Cristais?\\n\\nOs Cristais são pedras... \n",
197
- "\n",
198
- " Cristais/Cristais/Afixos.txt \\\n",
199
- "file name Cristais/Cristais/Afixos.txt \n",
200
- "content Afixos\\n\\n\\tMisericordioso\\nEsse inimigo ignor... \n",
201
- "\n",
202
- " Cristais/Cristais/Cristal de Gelo I/Bolinha de Neve.txt \\\n",
203
- "file name Cristais/Cristais/Cristal de Gelo I/Bolinha de... \n",
204
- "content Bolinha de neve (80HP AC 12)\\n\\nAfixos: Miseri... \n",
205
- "\n",
206
- " Cristais/Cristais/Cristal de Gelo I/Coruja.txt ... \\\n",
207
- "file name Cristais/Cristais/Cristal de Gelo I/Coruja.txt ... \n",
208
- "content Frostaluna (40HP 13AC)\\n\\n\\nAfixos: Misericord... ... \n",
209
- "\n",
210
- " Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Askad Edelmetall.txt \\\n",
211
- "file name Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Ask... \n",
212
- "content Askad Edelmetall\\né uma feiticeira nível 10, a... \n",
213
- "\n",
214
- " Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Atur Hammerhemd.txt \\\n",
215
- "file name Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Atu... \n",
216
- "content \n",
217
- "\n",
218
- " Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Quest G (Askad).txt \\\n",
219
- "file name Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Que... \n",
220
- "content Askad Edelmetall\\né uma feiticeira nível 10, a... \n",
221
- "\n",
222
- " Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Cozinheira (Thrinan).txt \\\n",
223
- "file name Mundo/Guildas/Guilda (Gelb Skarabäus)/NPCS/Coz... \n",
224
- "content Thrinan Kieselstein\\n\\né uma cozinheira anã da... \n",
225
- "\n",
226
- " Campanhas/A Cidade Dourada/Sessão 01.txt \\\n",
227
- "file name Campanhas/A Cidade Dourada/Sessão 01.txt \n",
228
- "content Retcon: \\nA viagem dos 4 foi conduzida por um ... \n",
229
- "\n",
230
- " Campanhas/A Cidade Dourada/Sessão 02.txt \\\n",
231
- "file name Campanhas/A Cidade Dourada/Sessão 02.txt \n",
232
- "content Recap:\\nNa sessão passada, nossos heróis(?) fo... \n",
233
- "\n",
234
- " Campanhas/A Cidade Dourada/Sessão 03.txt \\\n",
235
- "file name Campanhas/A Cidade Dourada/Sessão 03.txt \n",
236
- "content \n",
237
- "\n",
238
- " Campanhas/A Cidade Dourada/NPCs/Zackrias Bluff.txt \\\n",
239
- "file name Campanhas/A Cidade Dourada/NPCs/Zackrias Bluff... \n",
240
- "content \n",
241
- "\n",
242
- " Campanhas/A Cidade Dourada/Inimigos/Os Meninos.txt \\\n",
243
- "file name Campanhas/A Cidade Dourada/Inimigos/Os Meninos... \n",
244
- "content Primeiros Boss caso seja no armazem\\n\\n\\nOs Me... \n",
245
- "\n",
246
- " Campanhas/A Cidade Dourada/Inimigos/Ignacio.txt \n",
247
- "file name Campanhas/A Cidade Dourada/Inimigos/Ignacio.txt \n",
248
- "content Primeiro boss caso batalhem na caravana\\n\\n\\n\\... \n",
249
- "\n",
250
- "[2 rows x 56 columns]"
251
- ]
252
- },
253
- "execution_count": 26,
254
- "metadata": {},
255
- "output_type": "execute_result"
256
- }
257
- ],
258
- "source": [
259
- "from src.utils.get_data import get_data\n",
260
- "\n",
261
- "\n",
262
- "\n",
263
- "data = get_data()\n",
264
- "\n",
265
- "import pandas as pd\n",
266
- "df = pd.DataFrame.from_dict(data)\n",
267
- "df"
268
- ]
269
- },
270
- {
271
- "cell_type": "code",
272
- "execution_count": 9,
273
- "id": "f073a9c9",
274
- "metadata": {},
275
- "outputs": [
276
- {
277
- "data": {
278
- "text/html": [
279
- "<div>\n",
280
- "<style scoped>\n",
281
- " .dataframe tbody tr th:only-of-type {\n",
282
- " vertical-align: middle;\n",
283
- " }\n",
284
- "\n",
285
- " .dataframe tbody tr th {\n",
286
- " vertical-align: top;\n",
287
- " }\n",
288
- "\n",
289
- " .dataframe thead th {\n",
290
- " text-align: right;\n",
291
- " }\n",
292
- "</style>\n",
293
- "<table border=\"1\" class=\"dataframe\">\n",
294
- " <thead>\n",
295
- " <tr style=\"text-align: right;\">\n",
296
- " <th></th>\n",
297
- " <th>File Name</th>\n",
298
- " <th>Content</th>\n",
299
- " <th>Context</th>\n",
300
- " </tr>\n",
301
- " </thead>\n",
302
- " <tbody>\n",
303
- " <tr>\n",
304
- " <th>0</th>\n",
305
- " <td>asdasd</td>\n",
306
- " <td>asdasdasd</td>\n",
307
- " <td>asdasdasd</td>\n",
308
- " </tr>\n",
309
- " </tbody>\n",
310
- "</table>\n",
311
- "</div>"
312
- ],
313
- "text/plain": [
314
- " File Name Content Context\n",
315
- "0 asdasd asdasdasd asdasdasd"
316
- ]
317
- },
318
- "execution_count": 9,
319
- "metadata": {},
320
- "output_type": "execute_result"
321
- }
322
- ],
323
- "source": [
324
- "test = {'File Name': [], 'Content': [], 'Context': []}\n",
325
- "\n",
326
- "\n",
327
- "test['File Name'].append('asdasd')\n",
328
- "test['Content'].append('asdasdasd')\n",
329
- "test['Context'].append('asdasdasd')\n",
330
- "\n",
331
- "df2 = pd.DataFrame.from_dict(test)\n",
332
- "df2.head()"
333
- ]
334
- },
335
- {
336
- "cell_type": "code",
337
- "execution_count": 17,
338
- "id": "1d8236f5",
339
- "metadata": {},
340
- "outputs": [
341
- {
342
- "name": "stdout",
343
- "output_type": "stream",
344
- "text": [
345
- "O erro é: 0.03530823858545563\n"
346
- ]
347
- }
348
- ],
349
- "source": [
350
- "import math \n",
351
- "\n",
352
- "e = math.e\n",
353
- "k = 0.05\n",
354
- "\n",
355
- "\n",
356
- "def calculate_p(m):\n",
357
- " d = (10)\n",
358
- " d0 = 200\n",
359
- "\n",
360
- " I = (0.55)\n",
361
- " I = min(1, max(I,0))\n",
362
- "\n",
363
- " C = len(m.split(\" \"))/len(m)\n",
364
- " C = min(1, max(C, 0))\n",
365
- " d_critico = d0*((1-I)*(1-C))\n",
366
- " p_erro = 1/(1 + e**(-k*(d - d_critico)))\n",
367
- " print(f\"O erro é: {p_erro}\")\n",
368
- " return p_erro\n",
369
- "\n",
370
- "\n",
371
- "msg = \"sexo selvagem\"\n",
372
- "p_erro = calculate_p(msg)"
373
- ]
374
- },
375
- {
376
- "cell_type": "code",
377
- "execution_count": null,
378
- "id": "32b611de",
379
- "metadata": {},
380
- "outputs": [],
381
- "source": []
382
- }
383
- ],
384
- "metadata": {
385
- "kernelspec": {
386
- "display_name": "RPG-RAG",
387
- "language": "python",
388
- "name": "python3"
389
- },
390
- "language_info": {
391
- "codemirror_mode": {
392
- "name": "ipython",
393
- "version": 3
394
- },
395
- "file_extension": ".py",
396
- "mimetype": "text/x-python",
397
- "name": "python",
398
- "nbconvert_exporter": "python",
399
- "pygments_lexer": "ipython3",
400
- "version": "3.12.0"
401
- }
402
- },
403
- "nbformat": 4,
404
- "nbformat_minor": 5
405
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
legacy/src/utils/__init__.py DELETED
File without changes
legacy/src/utils/__pycache__/__init__.cpython-312.pyc DELETED
Binary file (148 Bytes)
 
legacy/src/utils/__pycache__/get_data.cpython-312.pyc DELETED
Binary file (1.29 kB)
 
legacy/src/utils/api_key.py DELETED
@@ -1,4 +0,0 @@
1
- import os
2
-
3
- OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
4
- PYANNOTE_API_KEY = os.getenv("PYANNOTE_API_KEY")
 
 
 
 
 
legacy/src/utils/get_data.py DELETED
@@ -1,30 +0,0 @@
1
- from pathlib import Path
2
-
3
-
4
- # project root (RPG-RAG/)
5
- PROJECT_ROOT = Path(__file__).resolve().parents[2]
6
-
7
- # Data/Ekalia
8
- DATA_DIR = PROJECT_ROOT / "Data" / "Ekalia"
9
-
10
-
11
- def get_data():
12
- data = {
13
- "File Name": [],
14
- "Context": [],
15
- "Content": [],
16
- }
17
-
18
- for file_path in DATA_DIR.rglob("*.txt"):
19
- content = file_path.read_text(encoding="utf-8")
20
-
21
- data["File Name"].append(file_path.name)
22
- data["Content"].append(content)
23
-
24
- # Context = relative path inside Ekalia
25
- context = file_path.parent.relative_to(DATA_DIR)
26
- data["Context"].append(str(context))
27
-
28
- print(f"Read file: {context}/{file_path.name} ({len(content)})")
29
-
30
- return data
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
main.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ def main():
2
+ print("Hello from rpg-rag!")
3
+
4
+
5
+ if __name__ == "__main__":
6
+ main()
pyproject.toml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [project]
2
+ name = "rpg-rag"
3
+ version = "0.1.0"
4
+ description = "Add your description here"
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ dependencies = [
8
+ "gradio>=6.9.0",
9
+ "groq>=1.1.1",
10
+ "langchain>=1.2.12",
11
+ "langchain-ollama>=1.0.1",
12
+ "langchain-openai>=1.1.11",
13
+ "openai>=2.28.0",
14
+ "openai-whisper>=20250625",
15
+ "pandas>=3.0.1",
16
+ "pillow>=12.1.1",
17
+ "pyannote-audio>=4.0.4",
18
+ "pymupdf>=1.23.0",
19
+ "torch>=2.10.0",
20
+ "torchaudio>=2.10.0",
21
+ "torchvision>=0.25.0",
22
+ ]
requirements.txt CHANGED
@@ -20,5 +20,4 @@ PyMuPDF>=1.23.0
20
  Pillow>=10.0.0
21
 
22
  # HF Spaces
23
- audioop-lts
24
  gradio>=5.0.0
 
20
  Pillow>=10.0.0
21
 
22
  # HF Spaces
 
23
  gradio>=5.0.0
src/llm/__pycache__/client.cpython-312.pyc CHANGED
Binary files a/src/llm/__pycache__/client.cpython-312.pyc and b/src/llm/__pycache__/client.cpython-312.pyc differ
 
uv.lock ADDED
The diff for this file is too large to render. See raw diff