# Tareas

Una **tarea** es un procedimiento con pasos que un Met ejecuta. A diferencia de un Run —que es una conversación puntual— la tarea se guarda, se versiona, se dispara sola y deja historial de cada corrida.

Usa los scopes `tasks:read` y `tasks:write`.

## El modelo en una frase

**La tarea es la receta; la ejecución es el plato.** Editas la tarea una vez; la ejecutas todas las veces que quieras, y cada ejecución tiene su propio estado, su propio historial y sus propias pausas.

```ts
const tarea = await met.tasks.create({
  title: 'Calificar leads nuevos',
  description: 'Revisa los contactos sin etapa y proponme una calificación.',
  agent_id: 12,
});

const ejecucion = await met.tasks.execute(tarea.id);
// → { id, status: 'running', ... }
```
```python
tarea = met.tasks.create(
    title="Calificar leads nuevos",
    description="Revisa los contactos sin etapa y proponme una calificación.",
    agent_id=12,
)

ejecucion = met.tasks.execute(tarea["id"])
# → { "id": ..., "status": "running", ... }
```
```bash
met tasks run tsk_123 --wait
```

La ejecución arranca en `running` y los pasos corren en segundo plano: lee
`met.tasks.execution(id)` para saber en qué quedó. Desde la terminal, `--wait` lo
espera por ti y refleja el resultado en el código de salida (ver [CLI](cli.html)).

## Pasos

Los pasos son lo que el Met hace, en orden. Se editan por separado de la tarea para que reordenar no reescriba todo.

```ts
await met.tasks.steps.create(tarea.id, {
  title: 'Traer contactos sin etapa',
  type: 'agent',
});

await met.tasks.steps.reorder(tarea.id, [pasoB.id, pasoA.id]);
```

`steps.updateResult()` te deja escribir el resultado de un paso desde afuera — útil cuando el trabajo real lo hizo tu sistema y solo quieres dejarlo registrado.

## Pausas para una persona

Es lo que distingue a una tarea de un script. Un paso puede detener la ejecución y esperar a alguien: hay dos formas y **no son la misma**.

**Aprobación** — el Met hizo el trabajo y pide permiso para seguir:

```ts
await met.tasks.approveStep(ejecucion.id, paso.id, 'Va, los montos cuadran');
await met.tasks.rejectStep(ejecucion.id, paso.id, 'El descuento no está autorizado');
```

Aprobar continúa hacia el siguiente paso de forma asíncrona. Rechazar detiene esa rama.

**Paso humano** — el trabajo lo hace la persona, no el Met:

```ts
await met.tasks.completeHumanStep(ejecucion.id, paso.id, 'Contrato firmado y archivado');
```

Úsalo cuando tu propio sistema hizo lo que el paso pedía: el executor avanza al siguiente.

> Las tres operan sobre el **id de la ejecución**, no el de la tarea. Es el error más común al integrar: el paso pertenece a la receta, pero la pausa pertenece a la corrida.

## Seguir una ejecución

```ts
const historial = await met.tasks.executions(tarea.id);
const estado = await met.tasks.execution(ejecucion.id);

await met.tasks.cancelExecution(ejecucion.id);
```

`cancelExecution()` no lleva `Idempotency-Key`: cancelar dos veces es inofensivo y no queremos que un reintento se coma la segunda cancelación.

Para reaccionar en vivo en vez de sondear, escucha los eventos de tarea por SSE — mira [Eventos en vivo](eventos.html).

## Disparadores

Un disparador ejecuta la tarea sin que nadie la llame: por horario, por evento del workspace o por webhook entrante.

```ts
await met.tasks.triggers.create(tarea.id, {
  type: 'schedule',
  cron: '0 9 * * 1',        // lunes 9am
});

await met.tasks.triggers.updatePrimary(tarea.id, { enabled: false });
```

`updatePrimary()` toca el disparador principal de la tarea sin que tengas que buscar su id.

## Comentarios y adjuntos

El hilo de la tarea acepta archivos. Se sube primero y se manda la metadata después:

```ts
const adjunto = await met.tasks.comments.upload(tarea.id, archivo, {
  filename: 'reporte.pdf',
  contentType: 'application/pdf',
});

await met.tasks.comments.create(tarea.id, {
  body: 'Adjunto el reporte del cierre.',
  attachments: [adjunto],
});
```

## Contexto y actividad

```ts
const actividad = await met.tasks.activity(tarea.id);          // de una tarea
const todo = await met.tasks.workspaceActivity({ limit: 50 }); // de todo el workspace

const vinculados = await met.tasks.linkedItems(tarea.id);      // ítems de colección
```

`linkedItems()` devuelve los ítems de colección atados a la tarea: es cómo una tarea trabaja sobre datos concretos en vez de sobre el vacío. Mira [Colecciones e ítems](colecciones-e-items.html).

## Vistas guardadas

Las vistas son del **workspace**, no de una tarea: filtros guardados sobre el listado.

```ts
await met.tasks.views.create({ name: 'Bloqueadas', filters: { status: 'blocked' } });
await met.tasks.views.reorder([vistaA.id, vistaB.id]);
```

## Estado

```ts
await met.tasks.setStatus(tarea.id, 'paused');
```

Pausar una tarea no detiene las ejecuciones en curso: impide que nazcan nuevas. Para cortar una corrida, `cancelExecution()`.
