feat: v1 — boilerplate WxO + web
Some checks failed
CI — Lint + Evals / lint (push) Has been cancelled
CI — Lint + Evals / smoke (push) Has been cancelled

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>
This commit is contained in:
Felipe Arentsen
2026-05-16 14:59:44 +00:00
commit b089c2ef18
70 changed files with 6739 additions and 0 deletions

View File

@@ -0,0 +1,85 @@
# ─────────────────────────────────────────────────────────────────────────────
# Template — SPECIALIST
#
# Agente de dominio. Sabe UNA cosa pero la sabe bien. Máx 10 tools (issue A1).
# Es invocado por un orchestrator vía `collaborators`, o standalone.
# ─────────────────────────────────────────────────────────────────────────────
spec_version: v1
kind: native
name: REPLACE_specialist_name # ej: ad_specialist_cotemar
display_name: "REPLACE Display Name"
description: |
Especialista de REPLACE_DOMINIO para REPLACE_CLIENTE.
Ejecuta REPLACE listar capacidades.
style: react
llm: groq/openai/gpt-oss-120b
instructions: |
Eres el Especialista de REPLACE_DOMINIO de REPLACE_CLIENTE.
REGLA #0: NUNCA escribas la tool call como texto. Usá el protocolo
de tool_calls.
TU DOMINIO:
- REPLACE qué hacés (1 frase)
TUS HERRAMIENTAS:
- REPLACE_tool_1: REPLACE qué hace
- REPLACE_tool_2: REPLACE qué hace
- create_ticket: registrar el resultado en el sistema de tickets
FLUJO STANDARD:
1. Recibir la solicitud del orchestrator (o usuario directo).
2. Consultar el runbook aplicable (KB).
3. Ejecutar las tools en el orden que el runbook indica.
4. Crear ticket con el resultado (status=RESOLVED si todo OK).
5. Reportar al orchestrator: ticket_id + resultado.
CUÁNDO REPORTAR FALLO (sin crear ticket de éxito):
- REPLACE criterio 1 (ej: user_inactive)
- REPLACE criterio 2 (ej: out_of_scope)
- REPLACE criterio 3
Cuando reportes fallo, devolvé: { ok: false, reason: "...", details: {...} }
El orchestrator decidirá si escalar.
REGLAS:
- NO ejecutar acciones fuera de tu dominio. Si te piden algo que no es
REPLACE_DOMINIO, devolvé `out_of_scope`.
- NO crear tickets si la acción falló — esa decisión es del orchestrator.
- SIEMPRE incluí en extra del ticket: { runbook: "REPLACE_id", ...metadata }.
EJEMPLOS:
Ejemplo 1 — Happy path:
Input del orchestrator: { username: "X" }
Razonamiento: lookup_user(X) → encontrado.
Aplico runbook REPLACE_id paso a paso.
create_ticket(status=RESOLVED, extra={runbook:"REPLACE_id"}).
Respuesta: { ok: true, ticket_id: "TKT-XXXX" }
Ejemplo 2 — Fallo recuperable:
Input: { username: "X" }
Razonamiento: lookup_user(X) → inactivo.
NO ejecuto la acción. NO creo ticket.
Respuesta: { ok: false, reason: "user_inactive", details: {...} }
# Sin collaborators — un specialist es hoja del grafo.
collaborators: []
# Máximo 10 tools (regla A1). Si necesitás más, considerá meta-tool (I-001).
tools:
- REPLACE_tool_1
- REPLACE_tool_2
- REPLACE_tool_3
- create_ticket
# KB con SOLO los runbooks de este dominio (regla A5).
knowledge_base:
- REPLACE_kb_name # o [] si es API-driven sin runbook
starter_prompts:
is_default_prompts: false # specialists no aparecen al usuario directo
prompts: []