Madras1 commited on
Commit
4956e79
·
verified ·
1 Parent(s): 1f9b97a

Upload 77 files

Browse files
app/config.py CHANGED
@@ -23,12 +23,15 @@ class Settings(BaseSettings):
23
  # Cerebras API for LLM-based entity extraction
24
  cerebras_api_key: str = ""
25
 
26
- # CORS
27
- cors_origins: list[str] = ["*"]
28
-
29
- # Session cookie
30
- cookie_secure: bool = True
31
- cookie_samesite: str = "none"
 
 
 
32
 
33
  class Config:
34
  env_file = ".env"
 
23
  # Cerebras API for LLM-based entity extraction
24
  cerebras_api_key: str = ""
25
 
26
+ # NumVerify API for phone lookup (free tier: 100 req/month)
27
+ numverify_api_key: str = ""
28
+
29
+ # CORS
30
+ cors_origins: list[str] = ["*"]
31
+
32
+ # Session cookie
33
+ cookie_secure: bool = True
34
+ cookie_samesite: str = "none"
35
 
36
  class Config:
37
  env_file = ".env"
app/services/investigator_agent.py CHANGED
@@ -117,6 +117,23 @@ TOOLS = [
117
  }
118
  }
119
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  {
121
  "type": "function",
122
  "function": {
@@ -304,6 +321,9 @@ class InvestigatorAgent:
304
  elif tool_name == "lookup_cnpj":
305
  return await self._lookup_cnpj(arguments.get("cnpj", ""))
306
 
 
 
 
307
  elif tool_name == "web_search":
308
  return await self._web_search(
309
  arguments.get("query", ""),
@@ -404,6 +424,53 @@ class InvestigatorAgent:
404
 
405
  return "CNPJ não encontrado."
406
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
407
  async def _web_search(self, query: str, freshness: str) -> str:
408
  """Web search via Lancer"""
409
  try:
 
117
  }
118
  }
119
  },
120
+ {
121
+ "type": "function",
122
+ "function": {
123
+ "name": "lookup_phone",
124
+ "description": "Consultar informações de um número de telefone. Retorna país, operadora, tipo de linha (fixo/móvel) e validade.",
125
+ "parameters": {
126
+ "type": "object",
127
+ "properties": {
128
+ "phone": {
129
+ "type": "string",
130
+ "description": "Número de telefone com código do país (ex: 5511999998888)"
131
+ }
132
+ },
133
+ "required": ["phone"]
134
+ }
135
+ }
136
+ },
137
  {
138
  "type": "function",
139
  "function": {
 
321
  elif tool_name == "lookup_cnpj":
322
  return await self._lookup_cnpj(arguments.get("cnpj", ""))
323
 
324
+ elif tool_name == "lookup_phone":
325
+ return await self._lookup_phone(arguments.get("phone", ""))
326
+
327
  elif tool_name == "web_search":
328
  return await self._web_search(
329
  arguments.get("query", ""),
 
424
 
425
  return "CNPJ não encontrado."
426
 
427
+ async def _lookup_phone(self, phone: str) -> str:
428
+ """Lookup phone number via NumVerify API"""
429
+ # Clean phone number - keep only digits
430
+ phone_clean = "".join(c for c in phone if c.isdigit())
431
+
432
+ # NumVerify API key (free tier: 100 req/month)
433
+ numverify_key = getattr(settings, 'numverify_api_key', None)
434
+
435
+ if not numverify_key:
436
+ # Fallback: just do a web search for the number
437
+ return await self._web_search(f'"{phone_clean}" telefone', "any")
438
+
439
+ try:
440
+ async with httpx.AsyncClient(timeout=10.0) as client:
441
+ response = await client.get(
442
+ "http://apilayer.net/api/validate",
443
+ params={
444
+ "access_key": numverify_key,
445
+ "number": phone_clean,
446
+ "country_code": "", # Auto-detect
447
+ "format": 1
448
+ }
449
+ )
450
+
451
+ if response.status_code == 200:
452
+ data = response.json()
453
+
454
+ if data.get("valid"):
455
+ result = {
456
+ "numero": data.get("international_format"),
457
+ "valido": True,
458
+ "pais": data.get("country_name"),
459
+ "codigo_pais": data.get("country_code"),
460
+ "operadora": data.get("carrier"),
461
+ "tipo_linha": data.get("line_type"), # mobile, landline, etc
462
+ "localizacao": data.get("location")
463
+ }
464
+ return json.dumps(result, ensure_ascii=False, indent=2)
465
+ else:
466
+ return f"Número {phone_clean} não é válido ou não foi encontrado."
467
+
468
+ return "Erro ao consultar número."
469
+
470
+ except Exception as e:
471
+ # Fallback to web search
472
+ return await self._web_search(f'"{phone_clean}" telefone', "any")
473
+
474
  async def _web_search(self, query: str, freshness: str) -> str:
475
  """Web search via Lancer"""
476
  try: