Arnés para agentes de programación con ejecución distribuida, aislamiento por usuario/proyecto, workers durables, herramientas con aprobación humana, flujo Git transaccional y proveedores gobernados.
cp .env.example .envAjusta como mínimo:
HOST_PROJECTS_ROOT=/home/workspace
APP_UID=1000
APP_GID=1000
POSTGRES_PASSWORD=una-clave-segura
REDIS_PASSWORD=una-clave-segura
MINIO_ROOT_PASSWORD=una-clave-segura
# Anthropic es el provider predeterminado.
DEFAULT_PROVIDER=anthropic
DEFAULT_MODEL=claude-sonnet-5
ANTHROPIC_API_KEY=sk-ant-...
OPENAI_API_KEY=sk-...Las claves de los providers están centralizadas en el archivo .env de la raíz del repositorio. También se puede usar ANTHROPIC_API_KEY_FILE, OPENAI_API_KEY_FILE u OLLAMA_API_KEY_FILE para leer el secreto desde un archivo montado en vez de escribirlo directamente en el .env.
Desde la raíz:
make upO directamente:
docker compose \
--env-file .env \
-f infraestructura/docker-compose.yml \
up --buildCuando backend, frontend y worker estén disponibles, el servicio access-info imprime en la consola las rutas de acceso:
Angular UI : http://localhost:8080
FastAPI : http://localhost:8000
API docs : http://localhost:8000/docs
Health : http://localhost:8000/api/health
Readiness : http://localhost:8000/api/ready
Metrics : http://localhost:8000/api/metrics
MinIO Console : http://localhost:9001
Qdrant Dashboard : http://localhost:6333/dashboard
La interfaz permite:
- Seleccionar o registrar un proyecto debajo de
HOST_PROJECTS_ROOT. - Crear una sesión aislada para ese proyecto.
- Cambiar provider y modelo desde la barra superior.
- Ajustar únicamente los controles declarados por el provider y el modelo seleccionado; la UI oculta los parámetros no soportados.
- Consultar modelos de Ollama instalados en el host.
- Visualizar el catálogo completo de tools incorporadas, MCP y administradas.
- Crear, editar, habilitar, deshabilitar y eliminar tools HTTP declarativas desde la web con rol
owneromaintainer.
Para un repositorio /home/workspace/mi-servicio, crea un proyecto con:
relative_path = mi-servicio
git_mode = required
La barra superior incluye el acceso Capabilities, organizado en dos pestañas:
- Skills: instrucciones reutilizables creadas y administradas desde la interfaz.
- Tools: tools incorporadas por el arnés, tools descubiertas mediante MCP e integraciones HTTP declarativas.
La creación web de integraciones no acepta código ejecutable ni secretos embebidos. Una integración HTTP define nombre, descripción, método, URL, JSON Schema de entrada, timeout y headers. Los headers sensibles deben usar referencias como ${CUSTOMER_API_TOKEN}; el valor real se proporciona en el .env raíz o mediante el mecanismo de secretos del despliegue.
Ejemplo de configuración en .env:
MANAGED_TOOLS_ENABLED=true
MANAGED_TOOL_ALLOWED_HOSTS=internal-tools.dmain.local
MANAGED_TOOL_MAX_RESPONSE_BYTES=1048576
MANAGED_TOOL_REFRESH_SECONDS=2
CUSTOMER_API_TOKEN=replace-with-secret-manager-in-productionPor defecto solo se permiten endpoints HTTPS públicos. Los destinos internos o HTTP plano requieren revisión y una entrada explícita en MANAGED_TOOL_ALLOWED_HOSTS. El runtime no sigue redirecciones, revalida DNS antes de cada ejecución, limita el tamaño de respuesta y aplica la política de aprobación de tools. Consulta docs/MANAGED_TOOLS.md.
Las skills se documentan en docs/MANAGED_SKILLS.md; solo usuarios con rol owner o maintainer pueden crear, editar, habilitar o eliminar capacidades administradas.
Browser / Angular
│
├── REST: proyectos, sesiones, providers, artifacts, evals
└── WebSocket: streaming y replay de eventos
│
FastAPI API
├── PostgreSQL + pgvector ── system of record
├── Redis Streams ────────── cola, eventos, locks, cancelación, HITL
├── MinIO ────────────────── parches y artefactos inmutables
├── Qdrant ───────────────── memoria vectorial opcional
└── Model Catalog ────────── allowlist y capacidades
│
Durable Workers
│
┌───────────┴───────────┐
│ Git worktree por run │
│ Policy + PathGuard │
│ Sandbox Docker │
│ Provider / MCP tools │
└───────────┬───────────┘
│
GitHub / GitLab / Azure DevOps
Guarda:
- Usuarios e identidad.
- Proyectos y membresías.
- Sesiones y conversaciones.
- Runs, estados y consumo.
- Solicitudes de aprobación.
- Auditoría.
- Catálogo de modelos.
- Metadatos de artefactos.
- Evals.
- Memoria con pgvector cuando está seleccionado.
Redis nunca es la fuente definitiva de conversaciones o auditoría.
Se usa para:
- Redis Streams como cola durable.
- Consumer groups y recuperación de mensajes abandonados.
- Dead-letter stream al superar reintentos.
- Event journal con cursor para reconexión WebSocket.
- Cancelaciones distribuidas.
- Aprobaciones HITL entre API y workers.
- Locks con renovación de lease.
- Heartbeats de workers.
Guarda outputs grandes fuera de PostgreSQL:
- Parches Git.
- Diffs.
- Resultados de herramientas truncados en UI/contexto.
- Snapshots y adjuntos futuros.
Los objetos son privados y se descargan mediante un endpoint autenticado que vuelve a comprobar la pertenencia del run al usuario.
El backend se selecciona con:
MEMORY_VECTOR_BACKEND=pgvectorO:
MEMORY_VECTOR_BACKEND=qdrantLa memoria se filtra siempre por user_id y project_id.
- Cada request deriva una identidad.
- Cada proyecto tiene owner y tabla de membresías.
- Las sesiones pertenecen a un usuario y un proyecto.
- Las consultas de sesiones, runs, artifacts y memoria se filtran por identidad.
- El workspace se resuelve debajo de
WORKSPACES_ROOT. - Se rechazan traversal, symlinks y rutas sensibles.
- En modo productivo se deben aceptar headers de identidad únicamente desde un reverse proxy autenticado.
Perfiles de identidad:
AUTH_MODE=localUso individual confiable.
AUTH_MODE=trusted_headersEl API solo registra y encola el run. El worker:
- Reclama el mensaje en Redis Streams.
- Adquiere un lock renovable por sesión.
- Comprueba idempotencia y cancelación.
- Crea el workspace transaccional.
- Ejecuta el agente y publica eventos.
- Persiste mensajes, uso y auditoría.
- Genera patch en MinIO.
- Crea commit y, opcionalmente, pull request.
- Confirma el mensaje.
Si un worker desaparece, otro puede reclamar el mensaje pendiente. Al superar los reintentos, el job se mueve a axiz:runs:dead-letter.
Para repositorios Git:
repositorio limpio
→ worktree aislado
→ branch agent/<project>/<run>
→ cambios aprobados
→ diff y artifact
→ commit
→ push opcional
→ PR/MR draft opcional
→ limpieza del worktree
La rama principal y el checkout original no se modifican.
Para directorios no Git en modo optional o disabled, el worker usa una copia efímera. Puede producir un patch, pero no escribe directamente sobre el directorio montado.
La configuración de credenciales y endpoints se realiza en:
.env
Variables principales:
| Provider | API key | Endpoint | Timeout |
|---|---|---|---|
| Anthropic | ANTHROPIC_API_KEY o ANTHROPIC_API_KEY_FILE |
ANTHROPIC_BASE_URL |
ANTHROPIC_TIMEOUT_SECONDS |
| OpenAI | OPENAI_API_KEY o OPENAI_API_KEY_FILE |
OPENAI_BASE_URL |
OPENAI_TIMEOUT_SECONDS |
| Ollama | OLLAMA_API_KEY o OLLAMA_API_KEY_FILE |
OLLAMA_DOCKER_BASE_URL |
OLLAMA_TIMEOUT_SECONDS |
Anthropic queda seleccionado por defecto en sesiones nuevas cuando su API key está configurada. Si no está configurado, la UI selecciona el primer provider habilitado y disponible para evitar crear una sesión inválida. Cada opción indica por qué no se puede seleccionar, diferenciando credenciales faltantes de un catálogo sin modelos habilitados.
Providers incluidos:
mockollamaopenaianthropic
El provider se puede cambiar desde Angular, pero solo se muestran modelos habilitados en:
config/model-catalog.yaml
El catálogo controla:
- Allowlist de provider/model.
- Estado habilitado/deshabilitado.
- Soporte de herramientas.
- Soporte de reasoning.
- Parámetros de generación admitidos por cada modelo.
- Contexto máximo.
- Output máximo.
- Valores predeterminados.
- Etiquetas y origen.
- Descubrimiento administrado de Ollama.
Los adapters reciben las capacidades desde el catálogo y solo serializan los parámetros admitidos por el modelo seleccionado. La UI aplica la misma metadata para ocultar controles incompatibles. No existen condicionales por nombre de modelo en el flujo de ejecución.
Los modelos pagados también deben registrarse en:
config/model-pricing.yaml
En el proyecto registra:
| Provider | remote_project |
|---|---|
| GitHub | owner/repository |
| GitLab | group/subgroup/repository |
| Azure DevOps | project/repository |
Configura el token correspondiente en .env y activa:
AUTO_CREATE_PULL_REQUEST=trueEl worker crea solicitudes draft después de hacer push de la rama transaccional.
Suites YAML:
config/evals/
Ejecuta el smoke test offline:
PYTHONPATH=backend/src \
python -m axiz.pe.coding_agent.evals.cli \
--suite smoke \
--provider mock \
--model mock-coding-agentLas evals verifican texto esperado, contenido prohibido y selección de herramientas. El resultado se guarda en la base de datos y el pipeline CI bloquea regresiones.
.
├── backend/
│ ├── src/axiz/pe/coding_agent/
│ │ ├── agent/
│ │ ├── api/
│ │ ├── approvals/
│ │ ├── artifacts/
│ │ ├── auth/
│ │ ├── evals/
│ │ ├── git/
│ │ ├── integrations/
│ │ ├── memory/
│ │ ├── models/
│ │ ├── persistence/
│ │ ├── providers/
│ │ ├── queue/
│ │ ├── sandbox/
│ │ ├── security/
│ │ ├── sessions/
│ │ ├── tools/
│ │ └── worker/
│ └── tests/
├── frontend/
├── config/
│ ├── evals/
│ ├── model-catalog.yaml
│ ├── model-pricing.yaml
│ ├── mcp.yaml
│ └── policies.yaml
├── infraestructura/
│ ├── docker/
│ ├── postgres/init/
│ ├── qdrant/
│ ├── redis/
│ ├── scripts/
│ └── docker-compose.yml
├── docs/
├── .env.example
├── Makefile
└── pyproject.toml
make init # crea .env
make up # levanta y muestra logs
make logs # sigue logs
make ps # estado
make test # pruebas backend
make down # detiene
make clean # elimina contenedores y volúmenesEl workflow .github/workflows/ci.yml se ejecuta únicamente a demanda mediante Run workflow (workflow_dispatch). No se dispara por push ni por pull_request.