Boilerplate completo para construir soluciones agénticas sobre IBM watsonx Orchestrate (ADK 2.x) con una capa web encima. Destilado de cotemar-poc-n1 y dun-casos-prueba. Incluye: - 11 docs (best practices, architecture patterns, ADK cheatsheet, observability, tool authoring, deployment, RUNBOOK, DEPLOY_TO_NEW_WOX, known-issues con 16 errores reales y fix, eval strategy, INDEX) - 13 templates WxO (orchestrator/specialist/single-meta agents, 3 connections, KB + runbook, observable_tool decorator, coercion helpers, Python tools, OpenAPI spec, backend filter endpoint, webhook validator HMAC, MCP connection) - 6 scripts (deploy idempotente con fallback ADK, undeploy, reset, check-adk-version, new-specialist scaffold, eval-agents runner) - 4 eval pieces (linter de best practices, runner, smoke-test, direct backend probe) + scenario templates - 8 subagentes Claude (.claude/agents/) — wxo-architect, wxo-agent-author, wxo-tool-author, runbook-author, mock-builder, backend-tool-builder, eval-author, web-layer-builder - Skill bundle fit-wxo-bootstrap/ (SKILL.md + 3 templates) listo para copiar a ~/.claude/skills/ - Web layer default FastAPI+HTMX con vista timeline observable + endpoint receptor de trazas - Docker compose Coolify-ready (healthcheck wget -qO-, sin labels Traefik, network split internal:true) - CI Gitea workflow con lint + smoke Best practices enforced por evals/lint_wxo_yaml.py: - A1: máx 10 tools por agente - A3: orchestrator sin tools de remediación - A6: agente sin propósito (react sin tools ni KB) - T1: @observable_tool obligatorio, no @tool directo - T3: _compat shim inline en tools.py - D1: docker-compose sin wget --spider - I-005: OpenAPI con description per-operation - I-009: sin labels Traefik manuales Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.6 KiB
Deployment Guide
Cómo desplegar una solución generada con este template. Cubre Coolify (default FIT) + alternativas.
Resumen
# 1. Tener el .env con las credenciales del tenant WxO y del host público
# 2. Tener un Coolify (o un docker host) corriendo
# 3. ./scripts/deploy-wxo.sh ← despliega agentes/tools/KBs/connections al tenant
# 4. docker compose up -d ← despliega la capa web + mocks (si los hay)
# 5. WxO UI → Embed Security OFF (manual, una vez por tenant)
# 6. ./evals/smoke-test.sh ← valida end-to-end
Variables de entorno requeridas
Ver .env.example para la lista completa. Las críticas:
# Tenant WxO
ORCHESTRATE_API_URL=https://api.us-south.watson-orchestrate.cloud.ibm.com/instances/<uuid>
ORCHESTRATE_API_KEY=<tu-api-key>
# Para Plan A (webhook a Runs API). Opcional.
WATSONX_API_KEY=<api-key-ibm-cloud>
IBM_CLOUD_IAM_URL=https://iam.cloud.ibm.com/identity/token
WXO_AGENT_ID=<uuid-del-orchestrator-en-live>
# Host público donde corre tu stack
PUBLIC_HOST=mi-cliente.fitlabs.dev
Coolify (FIT default)
Crear el stack
- Coolify panel → New Resource → Docker Compose
- Connect to git repo (Gitea)
- Build pack: docker compose, path
./docker-compose.yml - Domain: tu
PUBLIC_HOSTen el servicio que expone la landing/web - Env vars: copiar todos los valores del
.enval panel de Coolify - Deploy
Si Traefik da 503
Casi siempre es healthcheck. Verificá:
- El healthcheck usa
wget -qO-ocurl -sf(no--spider) → issue I-008 - El endpoint
/healthdel servicio responde 200 - En logs:
docker logs <container>busca errores de startup
Si sale "TRAEFIK DEFAULT CERT"
Tenés labels Traefik manuales en el compose. Borralos. Issue I-009.
Redeploy via API
curl -X POST "$COOLIFY_API_URL/applications/$COOLIFY_APP_UUID/deploy?force=true" \
-H "Authorization: Bearer $COOLIFY_API_TOKEN"
Docker Compose local
Para development. Trae el override docker-compose.local.yml que agrega
ports + bridge network.
cp .env.example .env
LANDING_PORT=18900 docker compose \
-f docker-compose.yml \
-f docker-compose.local.yml \
up -d --build
URLs:
- Landing:
http://localhost:18900/ - Web layer:
http://localhost:18900/web/ - Cualquier mock:
http://localhost:18900/<mock-name>/
Otros targets (K8s, Cloud Run, etc.)
El template es Docker-compose-first, pero los servicios son containers estándar. Para migrar:
- Kubernetes: convertir cada service del compose en
Deployment+Service. Usar un Ingress controller para el routing (estilo Traefik).kompose convertte da una primera versión. - Cloud Run: cada service va por separado. Las connections entre ellos por URLs HTTP públicas o VPC connector.
- ECS Fargate: task definition por service. ALB para el routing.
El WxO deploy (./scripts/deploy-wxo.sh) es independiente del target.
Lo que cambia es solo el host público que el ADK ve en las connections.
Deploy del WxO stack
./scripts/deploy-wxo.sh es idempotente. Hace:
- Connections en draft y live (issue I-004)
- Tools import (Python + OpenAPI según haya)
- KBs import
- Agents import (specialists primero, orchestrator último)
- Agents deploy a live
- Channel creation
Lo podés re-correr todas las veces que quieras.
Variables que afecta el script
| Var | Default | Para qué |
|---|---|---|
PUBLIC_HOST |
mi-cliente.fitlabs.dev |
Base URL de las connections |
WXO_ENV_NAME |
default |
Cuál env del ADK usar |
SKIP_TOOLS |
false |
Saltar la fase de tools (útil si solo cambiaste agentes) |
SKIP_KB |
false |
Saltar KBs (idem) |
Capturar IDs después del deploy
orchestrate agents list
# Buscá: mesa_n1 (o como se llame tu orchestrator)
# y su row con env=live
# Capturá: agent_id + env_id
Esos dos UUIDs van a:
web/.../index.html→agentId+agentEnvironmentIddel widget de chat.env→WXO_AGENT_ID(para Plan A webhook)- Coolify env vars
Paso manual obligatorio — Embed Security OFF
WxO Console → Settings → Embed Security → Off
Sin esto el embed se queda en "Cargando agente...". Issue I-007.
Smoke test
./evals/smoke-test.sh
Hace login → crea un caso → ejecuta → polea → assert. Si pasa, el deploy está OK.
Si algo falla
./evals/direct-backend-probe.sh— aísla auth/connection de logic./scripts/check-adk-version.sh— confirma que el ADK pinneado todavía es válidodocs/known-issues.md— los 16 errores conocidos con su fixdocs/RUNBOOK.md— operaciones de recovery