rafaelcleversystems commited on
Commit
071b8a3
·
verified ·
1 Parent(s): 92c2e6a

Versão 0.2.0

Browse files
Files changed (1) hide show
  1. pages/9_Tela9_Laudo.py +230 -230
pages/9_Tela9_Laudo.py CHANGED
@@ -1,230 +1,230 @@
1
-
2
- import streamlit as st
3
- from template import render_header, require_uploaded_pdf, CACHE, GERARCACHE
4
- from agents.criadornotatecnica import criadornotatecnica5, modelo, temperature, especializacao, top_p, viewpoint
5
- from bd.embeddings import get_embeddings
6
- from bd.bdv import buscar_por_embeddings
7
- import json
8
-
9
- st.set_page_config(page_title="Tela 9 — Laudo", layout="wide", initial_sidebar_state="collapsed")
10
- render_header()
11
-
12
- st.header("Tela 9 — Laudo (Markdown + Preview)")
13
-
14
- if not require_uploaded_pdf():
15
- st.stop()
16
-
17
- result = st.session_state["result_classificador"]
18
-
19
- def normas_para_strings(normas):
20
- resultado = []
21
-
22
- for norma in normas:
23
- partes = []
24
-
25
- # Campos básicos da norma
26
- partes.append(f"id_norma: {norma.get('id_norma')}")
27
- partes.append(f"espécie_normativa: {norma.get('especie_normativa')}")
28
- partes.append(f"sigla: {norma.get('sigla')}")
29
- partes.append(f"número: {norma.get('numero')}")
30
- partes.append(f"ano: {norma.get('ano')}")
31
- partes.append(f"órgão_emissor: {norma.get('orgao_emissor')}")
32
- partes.append(f"referência_completa: {norma.get('referencia_completa')}")
33
-
34
- # Artigos mencionados
35
- artigos = norma.get("artigos_mencionados", [])
36
- artigos_str_list = []
37
-
38
- for art in artigos:
39
- artigo_str = (
40
- f"artigo {art.get('artigo')}, "
41
- f"parágrafos: {', '.join(art.get('paragrafos', [])) or 'nenhum'}, "
42
- f"incisos: {', '.join(art.get('incisos', [])) or 'nenhum'}, "
43
- f"alíneas: {', '.join(art.get('alineas', [])) or 'nenhum'}, "
44
- f"fontes: {', '.join(art.get('ids_fontes_no_processo', []))}, "
45
- f"observação: {art.get('observacao_curta')}"
46
- )
47
- artigos_str_list.append(artigo_str)
48
-
49
- if artigos_str_list:
50
- partes.append("artigos_mencionados: " + " | ".join(artigos_str_list))
51
- else:
52
- partes.append("artigos_mencionados: nenhum")
53
-
54
- # Junta tudo em uma única string
55
- norma_str = " ; ".join(partes)
56
- resultado.append(norma_str)
57
-
58
- return resultado
59
-
60
-
61
- def pegarLegislacao(legislacoes_marcadas):
62
-
63
- textoleg = ""
64
- #legislacoes_marcadas = st.session_state.get("legislacao", [])
65
-
66
- if legislacoes_marcadas:
67
- for idx, legislacao in enumerate(legislacoes_marcadas, start=1):
68
- #print(f"{idx, legislacao}")
69
- embedding = get_embeddings([legislacao])
70
- resultados = buscar_por_embeddings(embedding, top_k=2)
71
-
72
- pontos = resultados.get("result", []) if resultados else []
73
- textoleg = f"{textoleg}\n\n**{[legislacao]}**\n\n"
74
- if pontos:
75
- print(f"Legislações similares encontradas para a legislação {idx}:")
76
- for i, ponto in enumerate(pontos, start=1):
77
- chave = ponto.get("id", "Sem ID")
78
- score = ponto.get("score", 0)
79
- payload = ponto.get("payload", {})
80
-
81
- conteudo = payload.get("conteudo", "")
82
-
83
- textoleg = f"{textoleg}\n\n- {conteudo}\n"
84
- else:
85
- print(f"Nenhum resultado encontrado para a legislação {idx}.")
86
-
87
- else:
88
- print("Marque pelo menos uma legislação para buscar similares.")
89
-
90
- return textoleg
91
-
92
-
93
- from typing import Any, Dict, List
94
-
95
- def _md_escape(text: str) -> str:
96
- # simples: evita quebrar markdown com quebras e mantém legível
97
- return (text or "").replace("\r\n", "\n").strip()
98
-
99
- def format_grupos_markdown(grupos: List[Dict[str, Any]]) -> str:
100
- linhas: List[str] = []
101
-
102
- for g in grupos:
103
- nome_grupo = _md_escape(g.get("nome_grupo", "Grupo sem nome"))
104
- status_grupo = _md_escape(g.get("status_grupo", ""))
105
-
106
- # Título do grupo (em negrito)
107
- #if status_grupo:
108
- # linhas.append(f"**{nome_grupo}** _(status do grupo: {status_grupo})_")
109
- #else:
110
- # linhas.append(f"**{nome_grupo}**")
111
-
112
- linhas.append(f"**{nome_grupo}**")
113
-
114
- itens = g.get("itens", []) or []
115
- if not itens:
116
- linhas.append("- (sem itens)")
117
- linhas.append("") # linha em branco
118
- continue
119
-
120
- for it in itens:
121
- desc = _md_escape(it.get("descricao_item", "Item sem descrição"))
122
- status = _md_escape(it.get("status", ""))
123
- evidencias = it.get("evidencias", []) or []
124
- pendencias = it.get("pendencias", []) or []
125
-
126
- # Cabeçalho do item
127
- if status:
128
- linhas.append(f"- **Item:** {desc}")
129
- linhas.append(f" - **Status:** {status}")
130
- else:
131
- linhas.append(f"- **Item:** {desc}")
132
-
133
- # Evidências
134
- if evidencias:
135
- linhas.append(" - **Evidências:**")
136
- for ev in evidencias:
137
- doc = _md_escape(ev.get("id_documento", ""))
138
- tipo = _md_escape(ev.get("tipo_documento", ""))
139
- loc = _md_escape(ev.get("localizacao", ""))
140
- resumo = _md_escape(ev.get("resumo_evidencia", ""))
141
-
142
- partes = []
143
- if doc: partes.append(f"doc: {doc}")
144
- if tipo: partes.append(f"tipo: {tipo}")
145
- if loc: partes.append(f"local: {loc}")
146
- if resumo: partes.append(f"resumo: {resumo}")
147
-
148
- linhas.append(f" - " + (" | ".join(partes) if partes else "(evidência sem detalhes)"))
149
- else:
150
- linhas.append(" - **Evidências:** (nenhuma)")
151
-
152
- # Pendências
153
- if pendencias:
154
- linhas.append(" - **Pendências:**")
155
- for p in pendencias:
156
- linhas.append(f" - {_md_escape(str(p))}")
157
- else:
158
- linhas.append(" - **Pendências:** (nenhuma)")
159
-
160
- linhas.append("") # linha em branco entre grupos
161
-
162
- return "\n".join(linhas).rstrip()
163
-
164
-
165
- #default_md = st.session_state.get("resumo_md") or (
166
- # "## Resumo Inicial\n\n"
167
- # "Escreva aqui um breve resumo da Nota Técnica.\n\n"
168
- # f"**Arquivo original**: {st.session_state.get('uploaded_pdf_name')}\n"
169
- #)
170
-
171
- entrar = True
172
-
173
- #default_md = ""
174
- if "notatecnica_md" not in st.session_state or st.session_state["notatecnica_md"] == "" or entrar == True:
175
- print("processando IA - gerando laudo")
176
- with st.spinner("🤖 Gerando Laudo com IA..."):
177
- nome_arquivo = "notatecnica.txt"
178
- if CACHE == False:
179
- #default_md = sumarizador5(st.session_state["uploaded_pdf_text"], model=modelo, temperature=temperature, especializacao=especializacao, top_p=top_p, viewpoint=viewpoint)
180
- #default_md = st.session_state["resumo_md"]
181
- p1 = st.session_state["resumo_md"]
182
- p2 = json.dumps(result["nota_tecnica"]["checklists"]["checklists"], ensure_ascii=False, indent=2)
183
- leg = normas_para_strings(result["nota_tecnica"]["normas_processo"]["normas"])
184
- p3 = pegarLegislacao(leg)
185
-
186
- p2_text = format_grupos_markdown(result["nota_tecnica"]["checklists"]["checklists"])
187
-
188
- default_md = f"""
189
- # LAUDO
190
-
191
- ## Cheklist
192
-
193
- {p2_text}
194
-
195
- ## Normas/Legislação
196
-
197
- {p3}
198
-
199
- ## Nota Técnica Básica
200
-
201
- {p1}
202
-
203
- """
204
- #default_md = criadornotatecnica5(st.session_state["uploaded_pdf_text"], model=modelo, temperature=temperature, especializacao=especializacao, top_p=top_p, viewpoint=viewpoint,
205
- # resultado_passo_1=p1, resultado_passo_2=p2, resultado_passo_3=p3)
206
- if GERARCACHE == True:
207
- with open(nome_arquivo, "w", encoding="utf-8") as arquivo:
208
- arquivo.write(default_md)
209
- else:
210
- with open(nome_arquivo, 'r', encoding="utf-8") as f:
211
- default_md = f.read()
212
- #print(default_md)
213
- else:
214
- default_md = st.session_state["notatecnica_md"]
215
-
216
-
217
- col1, col2 = st.columns([0.55, 0.45])
218
- with col1:
219
- st.session_state["notatecnica_md"] = st.text_area("Editar Laudo em Markdown", value=default_md, height=420)
220
-
221
- with col2:
222
- st.markdown("**Pré-visualização do Laudo**")
223
- st.markdown(st.session_state["notatecnica_md"], unsafe_allow_html=False)
224
-
225
- st.divider()
226
- col1x, col2x, col3x = st.columns([0.1, 0.1, 0.8])
227
- with col1x:
228
- st.page_link("pages/8_Tela8_Grupo5.py", label="⬅️ Voltar")
229
- with col2x:
230
- st.page_link("pages/10_Tela10_Conclusao.py", label="Próximo passo ➡️")
 
1
+
2
+ import streamlit as st
3
+ from template import render_header, require_uploaded_pdf, CACHE, GERARCACHE
4
+ #from agents.criadornotatecnica import criadornotatecnica5, modelo, temperature, especializacao, top_p, viewpoint
5
+ from bd.embeddings import get_embeddings
6
+ from bd.bdv import buscar_por_embeddings
7
+ import json
8
+
9
+ st.set_page_config(page_title="Tela 9 — Laudo", layout="wide", initial_sidebar_state="collapsed")
10
+ render_header()
11
+
12
+ st.header("Tela 9 — Laudo (Markdown + Preview)")
13
+
14
+ if not require_uploaded_pdf():
15
+ st.stop()
16
+
17
+ result = st.session_state["result_classificador"]
18
+
19
+ def normas_para_strings(normas):
20
+ resultado = []
21
+
22
+ for norma in normas:
23
+ partes = []
24
+
25
+ # Campos básicos da norma
26
+ partes.append(f"id_norma: {norma.get('id_norma')}")
27
+ partes.append(f"espécie_normativa: {norma.get('especie_normativa')}")
28
+ partes.append(f"sigla: {norma.get('sigla')}")
29
+ partes.append(f"número: {norma.get('numero')}")
30
+ partes.append(f"ano: {norma.get('ano')}")
31
+ partes.append(f"órgão_emissor: {norma.get('orgao_emissor')}")
32
+ partes.append(f"referência_completa: {norma.get('referencia_completa')}")
33
+
34
+ # Artigos mencionados
35
+ artigos = norma.get("artigos_mencionados", [])
36
+ artigos_str_list = []
37
+
38
+ for art in artigos:
39
+ artigo_str = (
40
+ f"artigo {art.get('artigo')}, "
41
+ f"parágrafos: {', '.join(art.get('paragrafos', [])) or 'nenhum'}, "
42
+ f"incisos: {', '.join(art.get('incisos', [])) or 'nenhum'}, "
43
+ f"alíneas: {', '.join(art.get('alineas', [])) or 'nenhum'}, "
44
+ f"fontes: {', '.join(art.get('ids_fontes_no_processo', []))}, "
45
+ f"observação: {art.get('observacao_curta')}"
46
+ )
47
+ artigos_str_list.append(artigo_str)
48
+
49
+ if artigos_str_list:
50
+ partes.append("artigos_mencionados: " + " | ".join(artigos_str_list))
51
+ else:
52
+ partes.append("artigos_mencionados: nenhum")
53
+
54
+ # Junta tudo em uma única string
55
+ norma_str = " ; ".join(partes)
56
+ resultado.append(norma_str)
57
+
58
+ return resultado
59
+
60
+
61
+ def pegarLegislacao(legislacoes_marcadas):
62
+
63
+ textoleg = ""
64
+ #legislacoes_marcadas = st.session_state.get("legislacao", [])
65
+
66
+ if legislacoes_marcadas:
67
+ for idx, legislacao in enumerate(legislacoes_marcadas, start=1):
68
+ #print(f"{idx, legislacao}")
69
+ embedding = get_embeddings([legislacao])
70
+ resultados = buscar_por_embeddings(embedding, top_k=2)
71
+
72
+ pontos = resultados.get("result", []) if resultados else []
73
+ textoleg = f"{textoleg}\n\n**{[legislacao]}**\n\n"
74
+ if pontos:
75
+ print(f"Legislações similares encontradas para a legislação {idx}:")
76
+ for i, ponto in enumerate(pontos, start=1):
77
+ chave = ponto.get("id", "Sem ID")
78
+ score = ponto.get("score", 0)
79
+ payload = ponto.get("payload", {})
80
+
81
+ conteudo = payload.get("conteudo", "")
82
+
83
+ textoleg = f"{textoleg}\n\n- {conteudo}\n"
84
+ else:
85
+ print(f"Nenhum resultado encontrado para a legislação {idx}.")
86
+
87
+ else:
88
+ print("Marque pelo menos uma legislação para buscar similares.")
89
+
90
+ return textoleg
91
+
92
+
93
+ from typing import Any, Dict, List
94
+
95
+ def _md_escape(text: str) -> str:
96
+ # simples: evita quebrar markdown com quebras e mantém legível
97
+ return (text or "").replace("\r\n", "\n").strip()
98
+
99
+ def format_grupos_markdown(grupos: List[Dict[str, Any]]) -> str:
100
+ linhas: List[str] = []
101
+
102
+ for g in grupos:
103
+ nome_grupo = _md_escape(g.get("nome_grupo", "Grupo sem nome"))
104
+ status_grupo = _md_escape(g.get("status_grupo", ""))
105
+
106
+ # Título do grupo (em negrito)
107
+ #if status_grupo:
108
+ # linhas.append(f"**{nome_grupo}** _(status do grupo: {status_grupo})_")
109
+ #else:
110
+ # linhas.append(f"**{nome_grupo}**")
111
+
112
+ linhas.append(f"**{nome_grupo}**")
113
+
114
+ itens = g.get("itens", []) or []
115
+ if not itens:
116
+ linhas.append("- (sem itens)")
117
+ linhas.append("") # linha em branco
118
+ continue
119
+
120
+ for it in itens:
121
+ desc = _md_escape(it.get("descricao_item", "Item sem descrição"))
122
+ status = _md_escape(it.get("status", ""))
123
+ evidencias = it.get("evidencias", []) or []
124
+ pendencias = it.get("pendencias", []) or []
125
+
126
+ # Cabeçalho do item
127
+ if status:
128
+ linhas.append(f"- **Item:** {desc}")
129
+ linhas.append(f" - **Status:** {status}")
130
+ else:
131
+ linhas.append(f"- **Item:** {desc}")
132
+
133
+ # Evidências
134
+ if evidencias:
135
+ linhas.append(" - **Evidências:**")
136
+ for ev in evidencias:
137
+ doc = _md_escape(ev.get("id_documento", ""))
138
+ tipo = _md_escape(ev.get("tipo_documento", ""))
139
+ loc = _md_escape(ev.get("localizacao", ""))
140
+ resumo = _md_escape(ev.get("resumo_evidencia", ""))
141
+
142
+ partes = []
143
+ if doc: partes.append(f"doc: {doc}")
144
+ if tipo: partes.append(f"tipo: {tipo}")
145
+ if loc: partes.append(f"local: {loc}")
146
+ if resumo: partes.append(f"resumo: {resumo}")
147
+
148
+ linhas.append(f" - " + (" | ".join(partes) if partes else "(evidência sem detalhes)"))
149
+ else:
150
+ linhas.append(" - **Evidências:** (nenhuma)")
151
+
152
+ # Pendências
153
+ if pendencias:
154
+ linhas.append(" - **Pendências:**")
155
+ for p in pendencias:
156
+ linhas.append(f" - {_md_escape(str(p))}")
157
+ else:
158
+ linhas.append(" - **Pendências:** (nenhuma)")
159
+
160
+ linhas.append("") # linha em branco entre grupos
161
+
162
+ return "\n".join(linhas).rstrip()
163
+
164
+
165
+ #default_md = st.session_state.get("resumo_md") or (
166
+ # "## Resumo Inicial\n\n"
167
+ # "Escreva aqui um breve resumo da Nota Técnica.\n\n"
168
+ # f"**Arquivo original**: {st.session_state.get('uploaded_pdf_name')}\n"
169
+ #)
170
+
171
+ entrar = True
172
+
173
+ #default_md = ""
174
+ if "notatecnica_md" not in st.session_state or st.session_state["notatecnica_md"] == "" or entrar == True:
175
+ print("processando IA - gerando laudo")
176
+ with st.spinner("🤖 Gerando Laudo com IA..."):
177
+ nome_arquivo = "notatecnica.txt"
178
+ if CACHE == False:
179
+ #default_md = sumarizador5(st.session_state["uploaded_pdf_text"], model=modelo, temperature=temperature, especializacao=especializacao, top_p=top_p, viewpoint=viewpoint)
180
+ #default_md = st.session_state["resumo_md"]
181
+ p1 = st.session_state["resumo_md"]
182
+ p2 = json.dumps(result["nota_tecnica"]["checklists"]["checklists"], ensure_ascii=False, indent=2)
183
+ leg = normas_para_strings(result["nota_tecnica"]["normas_processo"]["normas"])
184
+ p3 = pegarLegislacao(leg)
185
+
186
+ p2_text = format_grupos_markdown(result["nota_tecnica"]["checklists"]["checklists"])
187
+
188
+ default_md = f"""
189
+ # LAUDO
190
+
191
+ ## Cheklist
192
+
193
+ {p2_text}
194
+
195
+ ## Normas/Legislação
196
+
197
+ {p3}
198
+
199
+ ## Nota Técnica Básica
200
+
201
+ {p1}
202
+
203
+ """
204
+ #default_md = criadornotatecnica5(st.session_state["uploaded_pdf_text"], model=modelo, temperature=temperature, especializacao=especializacao, top_p=top_p, viewpoint=viewpoint,
205
+ # resultado_passo_1=p1, resultado_passo_2=p2, resultado_passo_3=p3)
206
+ if GERARCACHE == True:
207
+ with open(nome_arquivo, "w", encoding="utf-8") as arquivo:
208
+ arquivo.write(default_md)
209
+ else:
210
+ with open(nome_arquivo, 'r', encoding="utf-8") as f:
211
+ default_md = f.read()
212
+ #print(default_md)
213
+ else:
214
+ default_md = st.session_state["notatecnica_md"]
215
+
216
+
217
+ col1, col2 = st.columns([0.55, 0.45])
218
+ with col1:
219
+ st.session_state["notatecnica_md"] = st.text_area("Editar Laudo em Markdown", value=default_md, height=420)
220
+
221
+ with col2:
222
+ st.markdown("**Pré-visualização do Laudo**")
223
+ st.markdown(st.session_state["notatecnica_md"], unsafe_allow_html=False)
224
+
225
+ st.divider()
226
+ col1x, col2x, col3x = st.columns([0.1, 0.1, 0.8])
227
+ with col1x:
228
+ st.page_link("pages/8_Tela8_Grupo5.py", label="⬅️ Voltar")
229
+ with col2x:
230
+ st.page_link("pages/10_Tela10_Conclusao.py", label="Próximo passo ➡️")