Un agent que busca trabajo por su cuenta
"The agent finds work itself." Sin necesidad de que alguien lo llame: toma tareas del tablero por su cuenta.
De «que te llamen» a «buscar trabajo tú mismo»
El teammate de s09/s10 es pasivo: alguien necesita enviar un mensaje al inbox para que empiece; al terminar queda idle y espera a que lo llamen de nuevo.
El autonomous teammate de s11 es activo: cuando no tiene trabajo tampoco se detiene del todo; cada 5 segundos escanea el directorio .tasks/. Si ve una task sin dueño la reclama con claim_task y empieza a trabajar.
Teammate lifecycle:
+-------+
| spawn |
+---+---+
|
v
+-------+
| WORK | <-- bucle LLM tool_use
+---+---+
|
| stop_reason != tool_use OR tool_use("idle")
v
+-------+
| IDLE | poll cada 5 s, 12 veces = timeout 60 s
+---+---+
|
+--> ¿hay mensajes nuevos en inbox? → retomar WORK
|
+--> scan .tasks/, tarea sin dueño → claim → retomar WORK
|
+--> 60 s sin nada → status = shutdown, hilo termina
Auto-claim · «Coger tarea» del tablero
Función principal:
def scan_unclaimed_tasks() -> list: unclaimed = [] for f in sorted(TASKS_DIR.glob("task_*.json")): task = json.loads(f.read_text()) if (task.get("status") == "pending" and not task.get("owner") and not task.get("blockedBy")): unclaimed.append(task) return unclaimed
Tres filtros = pending + sin owner + sin blockedBy. Los tres son imprescindibles.
La acción de claim tiene un lock (_claim_lock) para evitar que dos agents reclamen la misma task simultáneamente: dentro del lock se vuelve a leer, se comprueba que owner sigue vacío y se escribe en disco la marca «in_progress» + owner.
Simula varios agents escaneando el tablero a la vez
3 teammates en estado idle y 3 tasks esperando ser reclamadas. Pulsa «Siguiente poll» para ver quién llega primero.
Identity reinjection · Saber quién eres después del compactado
s06 explicó que auto_compact reemplaza los mensajes con un resumen. Un autonomous agent que lleva horas corriendo puede activar esto fácilmente; tras el compactado el modelo no sabe su nombre ni su rol.
La solución de s11: al reclamar una nueva task, si len(messages) ≤ 3 (indica que acaba de compactarse), inserta automáticamente un bloque de identidad al inicio:
if len(messages) <= 3: messages.insert(0, { "role": "user", "content": f"<identity>You are 'alice', role: coder, team: my-team. Continue your work.</identity>", }) messages.insert(1, {"role":"assistant", "content": f"I am alice. Continuing."})
Este patrón se llama identity reinjection: se construye artificialmente un turno de conversación para «decirle al modelo quién es» y que recupere su sentido de rol.