# Instrucciones para el agente: Glink: encadena agentes con eventos y recuperación de estado

Pega este texto a tu agente (Claude Code, Codex, OpenCode, Hermes o el que uses) y dile «ayúdame a montarlo». Son los pasos para ponerlo en marcha; el porqué de cada pieza está en la guía completa.

- Dificultad: avanzado
- Proyecto: https://github.com/garyqlin/glink-engine (licencia MIT)
- Guía completa: https://lab.wisd.ai/hub/glink-engine

---

## Para el agente: cómo acompañar al usuario

1. Pregunta primero para qué lo quiere. Si su objetivo no necesita algún paso, sáltalo.
2. Antes de instalar, comprueba lo que ya tiene (versiones, claves, sistema operativo).
3. Avanza un paso cada vez: explica en una frase qué vas a hacer y deja que el usuario lo ejecute o lo apruebe.
4. Tras cada paso, comprueba que funcionó antes de seguir. Si falla, para y explica el error.
5. No inventes comandos ni opciones: si la documentación del proyecto contradice estos pasos, manda la documentación.
6. Al terminar, haz una prueba real con el objetivo del usuario y dile dónde profundizar.

---

## Pasos de configuración

### Paso 1: prepara la copia y las dependencias

Comprueba Git, Python ≥3.11, pip y un sistema POSIX (Linux o macOS): el código importa `fcntl` y `pwd`. En un entorno virtual activado:

```bash
git clone https://github.com/garyqlin/glink-engine.git
cd glink-engine
pip install -e .
pip install PyYAML
```

La segunda instalación adapta el README: `bus/agent_client.py` importa `yaml`, pero el manifiesto no declara PyYAML. No se han ejecutado instalaciones aquí.

### Paso 2: prueba el protocolo de un ejecutor

La versión consultada no implementa `POST /run`, aunque el README lo anuncia. Además, `glink-daemon.py` puede usar `BASE_DIR` sin definirlo cuando sus importaciones tienen éxito. Para este recorrido usa la API Python real, sin depender de ese lanzador.

Guarda como `ejecutor_prueba.py` este servidor de ensayo, adaptado al contrato de `bus/agent_client.py` y `daemon/core.py`. No es un agente con modelo: devuelve un resultado fijo para comprobar el envío de tareas y sus dependencias.

```python
import json
from http.server import BaseHTTPRequestHandler, HTTPServer

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.end_headers()
        self.wfile.write(b'{"status":"ok"}')

    def do_POST(self):
        data = json.loads(self.rfile.read(int(self.headers["Content-Length"])))
        print(data["message"], flush=True)
        self.send_response(200)
        self.send_header("Content-Type", "application/json")
        self.end_headers()
        self.wfile.write(b'{"reply":"resultado de prueba"}')

HTTPServer(("127.0.0.1", 8000), Handler).serve_forever()
```

Desde la raíz ejecuta `python3 ejecutor_prueba.py` y mantenlo abierto. El código utiliza el puerto predeterminado `8000` para el ejecutor `default`. Para agentes propios, el código admite `GLINK_AGENT_PORTS` como JSON de nombres y puertos numéricos; el README muestra URLs completas, que no coinciden con ese contrato.

### Paso 3: ejecuta dos pasos dependientes

En la misma raíz guarda `prueba_flujo.py`. La firma real requiere el nombre del proyecto y el diccionario del flujo; no acepta únicamente el nombre con `context`, como propone el README.

```python
from daemon.core import run_workflow

workflow = {
    "project": {"name": "prueba-r2", "title": "Prueba", "goal": "Comprobar dos pasos"},
    "steps": [
        {"id": "step-1", "executor": "default", "title": "Primero", "task": "Devuelve un resultado de prueba"},
        {"id": "step-2", "executor": "default", "title": "Segundo", "task": "Confirma el segundo paso", "depends_on": ["step-1"]},
    ],
}
run_workflow("prueba-r2", workflow)
```

En otra terminal con el mismo entorno, ejecuta `python3 prueba_flujo.py`. Conserva la carpeta de datos que cree el motor para revisar eventos y puntos de recuperación.

## Comprobación

Comprueba que ambos pasos terminan y que el ejecutor recibe primero la tarea inicial y después la dependiente. Revisa los eventos `task.started` y `task.completed` del proyecto `prueba-r2`. Detén el ejecutor con Ctrl+C al terminar. Esto comprueba coordinación con un ejecutor simulado; para usar modelos debes servir tus agentes con `GET /health` y `POST /ask`, cuerpo con `message` y `session`, y respuesta JSON con `reply`.

## Si algo falla

Revisa que el puerto 8000 esté libre y que ambas terminales usen el mismo entorno. Un `ModuleNotFoundError: yaml` indica que falta PyYAML. No uses `POST /run` ni la firma abreviada del SDK del README en esta revisión. Contrasta las adaptaciones con [agent_client.py](https://github.com/garyqlin/glink-engine/blob/main/bus/agent_client.py), [core.py](https://github.com/garyqlin/glink-engine/blob/main/daemon/core.py), [api.py](https://github.com/garyqlin/glink-engine/blob/main/daemon/api.py) y [el lanzador](https://github.com/garyqlin/glink-engine/blob/main/glink-daemon.py).
