Saltar al contenido

Contribuir

import { Aside } from ‘@astrojs/starlight/components’;

Formas de contribuir

  • Nueva herramienta OSINT: integrar un nuevo servicio como funcion async
  • Bug fix: corregir comportamiento incorrecto
  • Mejora de documentacion: clarificar, completar, traducir
  • Tests: aumentar la cobertura de tests
  • Nuevo tipo de entidad: extender la ontologia FTM
  • Traduccion de skills: adaptar para nuevos idiomas

Flujo de trabajo

Ventana de terminal
# 1. Fork del repositorio en GitHub
# 2. Clona tu fork
git clone https://github.com/tu-usuario/osint-ai-one.git
cd osint-ai-one
# 3. Crea una rama para tu cambio
git checkout -b feature/mi-nueva-herramienta
# 4. Instala en modo desarrollo
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pre-commit install
# 5. Haz tus cambios
# ...
# 6. Ejecuta los tests
pytest tests/ -v
ruff check src/ tests/
mypy src/
# 7. Commit y push
git add .
git commit -m "feat: añade herramienta X para consultar Y"
git push origin feature/mi-nueva-herramienta
# 8. Abre un Pull Request en GitHub

Añadir una nueva herramienta OSINT

Estructura de la funcion

Todas las herramientas siguen el mismo patron:

src/tools/mi_servicio.py
import os
import httpx
from src.cache import cached
@cached(ttl_seconds=86400)
async def mi_servicio_lookup(target: str) -> dict:
"""
Consulta Mi Servicio para obtener informacion sobre target.
Args:
target: IP, dominio u otro identificador
Returns:
dict con campos normalizados del servicio
"""
api_key = os.getenv("MI_SERVICIO_API_KEY")
if not api_key:
return {"error": "MI_SERVICIO_API_KEY no configurada"}
async with httpx.AsyncClient(timeout=30) as client:
response = await client.get(
f"https://api.miservicio.com/v1/lookup/{target}",
headers={"Authorization": f"Bearer {api_key}"}
)
response.raise_for_status()
data = response.json()
return {
"source": "miservicio",
"target": target,
"result_field": data.get("field"),
# ... normaliza los campos relevantes
}

Registrar en el agente

En src/agent/__init__.py, añade la herramienta a la lista de tools del agente ReAct.

Registrar en el MCP Server

En src/mcp_server/server.py, añade un endpoint MCP para la herramienta.

Tests obligatorios

tests/tools/test_mi_servicio.py
import pytest
import respx
from httpx import Response
from src.tools.mi_servicio import mi_servicio_lookup
@pytest.mark.asyncio
@respx.mock
async def test_mi_servicio_lookup_success():
respx.get("https://api.miservicio.com/v1/lookup/8.8.8.8").mock(
return_value=Response(200, json={"field": "value"})
)
result = await mi_servicio_lookup("8.8.8.8")
assert result["result_field"] == "value"
assert result["source"] == "miservicio"
@pytest.mark.asyncio
@respx.mock
async def test_mi_servicio_lookup_error():
respx.get("https://api.miservicio.com/v1/lookup/8.8.8.8").mock(
return_value=Response(404)
)
result = await mi_servicio_lookup("8.8.8.8")
assert "error" in result

Documentar en .env.example

Ventana de terminal
# Mi Servicio — https://miservicio.com/register
MI_SERVICIO_API_KEY=

Convenciones de codigo

ElementoConvencion
Funciones de herramientanombre_servicio_tipo_lookup
Variables envSERVICIO_API_KEY en mayusculas
ImportacionesOrdenadas: stdlib → third-party → local
Formatoruff format (line length: 88)
Type hintsObligatorios en funciones publicas
DocstringsGoogle style, en ingles

Convenciones de commits

feat: nueva herramienta para X
fix: corrige error en Y cuando Z
docs: añade documentacion de W
test: tests para herramienta V
refactor: extrae logica compartida de cache
chore: actualiza dependencias

Codigo de conducta

Contribuciones respetuosas y constructivas. Critica el codigo, no a las personas.