Upload 77 files
Browse files
app/services/__pycache__/investigator_agent.cpython-311.pyc
CHANGED
|
Binary files a/app/services/__pycache__/investigator_agent.cpython-311.pyc and b/app/services/__pycache__/investigator_agent.cpython-311.pyc differ
|
|
|
app/services/investigator_agent.py
CHANGED
|
@@ -3,6 +3,7 @@ Investigator Agent - Autonomous Investigation with Tool Calling
|
|
| 3 |
Uses Cerebras native tool calling for multi-source investigations
|
| 4 |
"""
|
| 5 |
import json
|
|
|
|
| 6 |
import httpx
|
| 7 |
from typing import Optional, List, Dict, Any
|
| 8 |
from dataclasses import dataclass, field
|
|
@@ -15,6 +16,32 @@ from app.services.brazil_apis import consultar_cnpj
|
|
| 15 |
from app.models.entity import Entity, Relationship
|
| 16 |
|
| 17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
@dataclass
|
| 19 |
class Finding:
|
| 20 |
"""A discovery made during investigation"""
|
|
@@ -180,7 +207,7 @@ TOOLS = [
|
|
| 180 |
]
|
| 181 |
|
| 182 |
|
| 183 |
-
SYSTEM_PROMPT = """Você é um agente investigador autônomo do sistema NUMIDIUM/AVANGARD.
|
| 184 |
|
| 185 |
Sua missão é investigar temas usando múltiplas fontes de dados:
|
| 186 |
- NUMIDIUM: Grafo de conhecimento com entidades e relacionamentos
|
|
@@ -200,7 +227,8 @@ Sua missão é investigar temas usando múltiplas fontes de dados:
|
|
| 200 |
- Seja metódico e siga pistas
|
| 201 |
- Não invente informações - use apenas dados das ferramentas
|
| 202 |
- Priorize qualidade sobre quantidade
|
| 203 |
-
- Cite sempre as fontes
|
|
|
|
| 204 |
|
| 205 |
|
| 206 |
class InvestigatorAgent:
|
|
@@ -462,9 +490,22 @@ class InvestigatorAgent:
|
|
| 462 |
if not final_summary:
|
| 463 |
final_summary = await self._generate_report(mission)
|
| 464 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 465 |
return InvestigationResult(
|
| 466 |
mission=mission,
|
| 467 |
-
findings=
|
| 468 |
entities_discovered=self.entities_discovered,
|
| 469 |
connections_mapped=self.connections_mapped,
|
| 470 |
report=final_summary,
|
|
@@ -502,7 +543,7 @@ Gere relatório estruturado com: Resumo Executivo, Descobertas, Entidades, Recom
|
|
| 502 |
{"role": "user", "content": prompt}
|
| 503 |
])
|
| 504 |
|
| 505 |
-
return response["choices"][0]["message"]["content"]
|
| 506 |
|
| 507 |
|
| 508 |
# Singleton
|
|
|
|
| 3 |
Uses Cerebras native tool calling for multi-source investigations
|
| 4 |
"""
|
| 5 |
import json
|
| 6 |
+
import re
|
| 7 |
import httpx
|
| 8 |
from typing import Optional, List, Dict, Any
|
| 9 |
from dataclasses import dataclass, field
|
|
|
|
| 16 |
from app.models.entity import Entity, Relationship
|
| 17 |
|
| 18 |
|
| 19 |
+
def sanitize_text(text: str) -> str:
|
| 20 |
+
"""
|
| 21 |
+
Clean up text from Qwen model that may contain thinking artifacts.
|
| 22 |
+
Removes special characters like ‖ that appear when thinking leaks through.
|
| 23 |
+
"""
|
| 24 |
+
if not text:
|
| 25 |
+
return text
|
| 26 |
+
|
| 27 |
+
# Remove thinking tags and content between them
|
| 28 |
+
text = re.sub(r'<think>.*?</think>', '', text, flags=re.DOTALL)
|
| 29 |
+
text = re.sub(r'<\|think\|>.*?<\|/think\|>', '', text, flags=re.DOTALL)
|
| 30 |
+
|
| 31 |
+
# Remove the ‖ character that appears in buggy output (Unicode 2016)
|
| 32 |
+
text = text.replace('\u2016', '')
|
| 33 |
+
text = text.replace('‖', '')
|
| 34 |
+
|
| 35 |
+
# Remove other common thinking artifacts
|
| 36 |
+
text = re.sub(r'<\|.*?\|>', '', text)
|
| 37 |
+
|
| 38 |
+
# Clean up excessive whitespace
|
| 39 |
+
text = re.sub(r'\n{3,}', '\n\n', text)
|
| 40 |
+
text = re.sub(r' {2,}', ' ', text)
|
| 41 |
+
|
| 42 |
+
return text.strip()
|
| 43 |
+
|
| 44 |
+
|
| 45 |
@dataclass
|
| 46 |
class Finding:
|
| 47 |
"""A discovery made during investigation"""
|
|
|
|
| 207 |
]
|
| 208 |
|
| 209 |
|
| 210 |
+
SYSTEM_PROMPT = """Você é um agente investigador autônomo do sistema NUMIDIUM/AVANGARD. /no_think
|
| 211 |
|
| 212 |
Sua missão é investigar temas usando múltiplas fontes de dados:
|
| 213 |
- NUMIDIUM: Grafo de conhecimento com entidades e relacionamentos
|
|
|
|
| 227 |
- Seja metódico e siga pistas
|
| 228 |
- Não invente informações - use apenas dados das ferramentas
|
| 229 |
- Priorize qualidade sobre quantidade
|
| 230 |
+
- Cite sempre as fontes
|
| 231 |
+
- NÃO use pensamento interno ou tags <think>. Responda diretamente."""
|
| 232 |
|
| 233 |
|
| 234 |
class InvestigatorAgent:
|
|
|
|
| 490 |
if not final_summary:
|
| 491 |
final_summary = await self._generate_report(mission)
|
| 492 |
|
| 493 |
+
# Sanitize all text outputs to remove thinking artifacts
|
| 494 |
+
final_summary = sanitize_text(final_summary)
|
| 495 |
+
|
| 496 |
+
# Sanitize findings content
|
| 497 |
+
sanitized_findings = []
|
| 498 |
+
for f in self.findings:
|
| 499 |
+
sanitized_findings.append(Finding(
|
| 500 |
+
title=sanitize_text(f.title),
|
| 501 |
+
content=sanitize_text(f.content),
|
| 502 |
+
source=f.source,
|
| 503 |
+
timestamp=f.timestamp
|
| 504 |
+
))
|
| 505 |
+
|
| 506 |
return InvestigationResult(
|
| 507 |
mission=mission,
|
| 508 |
+
findings=sanitized_findings,
|
| 509 |
entities_discovered=self.entities_discovered,
|
| 510 |
connections_mapped=self.connections_mapped,
|
| 511 |
report=final_summary,
|
|
|
|
| 543 |
{"role": "user", "content": prompt}
|
| 544 |
])
|
| 545 |
|
| 546 |
+
return sanitize_text(response["choices"][0]["message"]["content"])
|
| 547 |
|
| 548 |
|
| 549 |
# Singleton
|