> ## Documentation Index
> Fetch the complete documentation index at: https://docs.puente.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Workflows

> Constructor visual de automatizaciones con triggers, código Python, agentes IA y peticiones HTTP integrado al workspace.

<Frame>
  <img src="https://mintcdn.com/puenteos/MFY1kiPfI9fyixWy/images/Screenshot-2026-06-03-at-3.49.33-PM.png?fit=max&auto=format&n=MFY1kiPfI9fyixWy&q=85&s=69406308fd45a578cfcec0cbee3f9d8c" alt="Screenshot 2026 06 03 At 3 49 33 PM" width="1782" height="1013" data-path="images/Screenshot-2026-06-03-at-3.49.33-PM.png" />
</Frame>

**Workflows** es el constructor visual de automatizaciones de Puente OS, similar a Make o Zapier pero integrado directamente con tu workspace. Diseñas el flujo arrastrando nodos en un canvas, los conectas con líneas, configuras cada paso con formularios dinámicos, código Python o agentes de IA, y los ejecutas con un trigger manual, webhook o cron.

Con Workflows puedes:

* Diseñar flujos arrastrando y conectando nodos en un canvas interactivo
* Ejecutar código Python en un sandbox seguro, nodo por nodo
* Integrar servicios externos (HTTP, email, databases) con formularios dinámicos
* Desplegar agentes de IA con prompts estructurados dentro del flujo
* Generar flujos completos describiéndolos en lenguaje natural con el asistente IA
* Versionar cada cambio del flujo de forma automática
* Probar nodos individualmente antes de ejecutar el flujo completo

### Navegación

| Acción           | Cómo                                           |
| ---------------- | ---------------------------------------------- |
| Mover el canvas  | Click y arrastra el fondo                      |
| Hacer zoom       | Rueda del mouse sobre el canvas                |
| Centrar vista    | Botón de controls (esquina inferior izquierda) |
| Mover un nodo    | Click y arrastra el nodo                       |
| Seleccionar nodo | Click en el nodo                               |
| Deseleccionar    | Click en el fondo del canvas                   |

***

## Tipos de nodo

<CardGroup cols={2}>
  <Card title="Trigger" icon="bolt">
    Punto de inicio del flujo. Manual, Webhook o Cron.
  </Card>

  <Card title="Acción" icon="plug">
    Integraciones predefinidas (email, HTTP, databases, etc).
  </Card>

  <Card title="HTTP Request" icon="globe">
    Peticiones HTTP estilo Postman con import desde cURL.
  </Card>

  <Card title="Código Python" icon="code">
    Sandbox Python con asistente IA integrado.
  </Card>

  <Card title="Agente IA" icon="robot">
    Ejecuta un prompt contra un modelo de lenguaje.
  </Card>

  <Card title="Comentario" icon="note">
    Anotación visual para documentar el flujo.
  </Card>
</CardGroup>

***

## Crear tu primer flujo

<Steps>
  <Step title="Agrega el Trigger">
    Un flujo nuevo abre con el botón **+ Agregar Trigger**. Haz click y elige el tipo de trigger en el Node Picker (por ejemplo, *Manual / Run Once*).
  </Step>

  <Step title="Agrega pasos">
    Tienes tres formas de agregar un paso después del trigger:

    * **Botón `+` del nodo** — aparece al pasar el cursor sobre un nodo y abre el Node Picker.
    * **Botón `+ Paso` de la toolbar** — agrega un nodo en la posición más baja del canvas.
    * **Asistente IA** — describe el flujo completo y la IA lo genera por ti.
  </Step>

  <Step title="Elige la integración">
    En el Node Picker, las integraciones se organizan por categoría (Core Tools, Comunicación, IA, etc). Busca por nombre o filtra por categoría y haz click para agregarla al canvas.
  </Step>

  <Step title="Conecta y configura">
    Conecta los nodos arrastrando entre sus handles y configura cada uno desde su panel (icono de lápiz).
  </Step>
</Steps>

***

## Trigger — el punto de inicio

Solo puede existir **un trigger** por flujo. No se puede eliminar (icono de candado) y define cómo se dispara el flujo:

### Trigger Manual (Run Once)

Sin configuración adicional. Se dispara con el botón **Ejecutar** en la toolbar. Útil para flujos one-shot o testing.

### Trigger Webhook

Genera una URL que puedes registrar en sistemas externos. Cualquier `POST` a esa URL dispara el flujo. El body de la petición queda disponible como `{{trigger_data}}` en los nodos siguientes.

<Warning>
  El workflow debe estar **guardado** antes de que la URL del webhook sea funcional.
</Warning>

### Trigger Schedule (Cron)

| Campo              | Descripción                                                              |
| ------------------ | ------------------------------------------------------------------------ |
| **Expresión Cron** | Define cuándo se ejecuta (`0 9 * * 1-5` = lunes a viernes a las 9:00 AM) |
| **Timezone**       | Zona horaria (ej. `America/Santiago`, `America/Mexico_City`)             |

Para activar el cron, el flujo debe estar guardado. Al hacer click en **Activar** se registra automáticamente.

***

## Nodos de Acción

Cada nodo de Acción ejecuta una integración predefinida (enviar email, escribir en una database, petición HTTP, etc.). Al hacer click en el icono de lápiz se abre un panel con un formulario dinámico por cada parámetro de la integración:

| Tipo de campo | Cómo se muestra                               |
| ------------- | --------------------------------------------- |
| `string`      | Textarea con Variable Picker                  |
| `number`      | Input numérico                                |
| `dropdown`    | Select con opciones                           |
| `boolean`     | Toggle                                        |
| `json`        | Textarea monospace                            |
| `credential`  | Input password con botón para mostrar/ocultar |

Click en **Guardar** para guardar sin ejecutar, o **Ejecutar** para correr ese nodo aislado.

### HTTP Request

El nodo HTTP Request es una versión especializada con interfaz estilo **Postman**: params, headers, autenticación y body. Acepta importación directa desde comandos cURL.

***

## Nodo de Código (Python)

Sandbox Python con syntax highlighting completo. Ejecuta el script de forma segura nodo por nodo.

### Variables de nodos anteriores

Referencia outputs de pasos previos con `{{context_key.campo}}`. Las referencias se resuelven justo antes de ejecutar, sustituyendo el placeholder por el valor Python equivalente:

```python theme={null}
# Si fetch_datos_1 retornó: { "nombre": "Ana", "saldo": 1500 }

cliente = "{{fetch_datos_1.nombre}}"
saldo = {{fetch_datos_1.saldo}}

if saldo > 1000:
    return {"status": "vip", "cliente": cliente}
else:
    return {"status": "regular", "cliente": cliente}
```

### Asistente IA en el nodo

El editor incluye un asistente IA que entiende el código actual y puede generar código desde cero, modificar o extender el existente, explicar qué hace o detectar y corregir errores. El código generado se inserta automáticamente en el editor. Puedes elegir el modelo de IA del chat.

***

## Nodo de Agente IA

Ejecuta un prompt contra un modelo de lenguaje, con selector de modelo. Tiene dos modos de configuración y un chat de prueba integrado.

<Tabs>
  <Tab title="Smart Mode">
    Formulario estructurado que se compila automáticamente en un prompt:

    * **Rol** — quién es el agente
    * **Tarea** — qué debe hacer
    * **Contexto** — información de fondo relevante
    * **Guidelines** — estilo y tono
    * **Restricciones** — qué NO debe hacer
    * **Output** — cómo estructurar la respuesta

    Cada campo admite referencias `{{context_key.campo}}` con preview del valor resuelto.
  </Tab>

  <Tab title="Manual Mode">
    Textarea libre donde escribes el prompt completo. Los cambios hechos en Smart Mode se sincronizan aquí automáticamente.
  </Tab>
</Tabs>

### Campo Input y chat de prueba

El campo **Input** define la entrada de datos del agente (texto libre o una referencia `{{context_key.campo}}`). El **chat de prueba** te deja probar el agente de forma interactiva antes de usarlo en el flujo:

| Escenario              | Mensaje enviado al agente             |
| ---------------------- | ------------------------------------- |
| Solo Input             | El valor del Input                    |
| Solo mensaje de prueba | El texto del chat                     |
| Input + mensaje        | `Input` seguido del mensaje de prueba |

<Tip>
  Si el modelo soporta razonamiento interno, aparece un indicador naranja pulsante: haz click para ver el razonamiento del agente.
</Tip>

***

## Sistema de variables `{{ }}`

Todos los campos de texto soportan referencias a outputs de nodos anteriores.

### Sintaxis

```text theme={null}
{{nombre_del_nodo_N.campo.subcampo}}
```

Donde `nombre_del_nodo_N` es el **context key**: `label` + `_` + número de secuencia.

| Nodo         | Label          | Nº secuencia | Context Key      |
| ------------ | -------------- | ------------ | ---------------- |
| Trigger      | `run_once`     | (ninguno)    | `run_once`       |
| Primer paso  | `fetch_datos`  | `1`          | `fetch_datos_1`  |
| Segundo paso | `procesar`     | `2`          | `procesar_2`     |
| Tercer paso  | `enviar_email` | `3`          | `enviar_email_3` |

### Ejemplo

Si `fetch_datos_1` retorna `{ "nombre": "Ana", "email": "ana@empresa.com" }`, en el siguiente nodo puedes usar:

```text theme={null}
Asunto: Hola {{fetch_datos_1.nombre}}
Destinatario: {{fetch_datos_1.email}}
```

### Variable Picker

Click en **`{ } Variables`** en cualquier campo y se abre el picker con todos los outputs disponibles de nodos upstream que ya fueron ejecutados en la sesión. Organiza los campos por nodo, muestra su tipo y, al seleccionar uno, lo inserta automáticamente.

***

## Conectar nodos

<Steps>
  <Step title="Localiza los handles">
    Handle de salida = parte inferior del nodo. Handle de entrada = parte superior.
  </Step>

  <Step title="Arrastra de salida a entrada">
    Pasa el cursor sobre el handle de salida, haz click y arrastra hacia el handle de entrada del siguiente nodo.
  </Step>

  <Step title="Suelta">
    La conexión se crea con estilo `smoothstep`.
  </Step>
</Steps>

### Indicadores visuales

| Color        | Significado                          |
| ------------ | ------------------------------------ |
| Borde oscuro | Estado normal                        |
| Verde        | Conexión válida (mientras arrastras) |
| Rojo         | Conexión inválida                    |

### Eliminar una conexión

Click en la línea y presiona `Delete` o `Backspace`.

<Note>
  El flujo se ejecuta siguiendo el orden de las conexiones, de arriba hacia abajo. Si un nodo no está conectado, se agrega al final de la secuencia.
</Note>

***

## Guardar y versionar

### Primer guardado

Al guardar por primera vez (botón **Guardar** o `Cmd/Ctrl + S`):

1. Se crea el flujo en el backend
2. Se asigna la versión 1
3. Aparece la pill superior con el nombre editable

### Guardados posteriores

Cada guardado crea una **nueva versión** del mismo flujo (v2, v3, etc.). La versión más reciente es la activa y la que se ejecuta por defecto; las anteriores quedan disponibles en el historial.

### Estado activo/inactivo

| Estado     | Descripción                                       |
| ---------- | ------------------------------------------------- |
| `draft`    | Borrador — en construcción                        |
| `active`   | Habilitado para ejecución desde sistemas externos |
| `inactive` | Deshabilitado temporalmente                       |

<Note>
  Para triggers de tipo **Schedule**, activar el flujo registra el cron automáticamente. Antes de activar, asegúrate de tener el flujo guardado.
</Note>

***

## Ejecutar el flujo

Click en **Ejecutar** en la toolbar inferior.

### Qué ocurre

1. El canvas se bloquea con overlay "Ejecutando…"
2. El backend ejecuta los nodos en orden topológico
3. Cada nodo pasa por los estados `pending`, `running`, `completed` o `failed`
4. Al finalizar se muestran los resultados

### Comportamiento ante errores

Cada nodo tiene un setting `on_error`:

| Valor              | Comportamiento                                                           |
| ------------------ | ------------------------------------------------------------------------ |
| **Stop** (default) | Si falla, el flujo se detiene y los nodos siguientes quedan en `pending` |
| **Continue**       | Si falla, registra el error y sigue con el siguiente nodo                |

### Ejecutar nodos individualmente

Desde el panel de cualquier nodo (icono de lápiz y luego **Ejecutar**), puedes correr ese nodo aislado. Útil para testing iterativo. El resultado queda disponible como variable `{{context_key.campo}}` para los nodos siguientes en la sesión.

***

## Panel de Resultados e Historial

### Resultados

Aparece automáticamente al ejecutar un nodo. Muestra:

* **Resultado** — Output en JSON con árbol interactivo
* **Logs** — stdout y stderr
* **Error** — mensaje de error si falló
* **Historial** — ejecuciones anteriores del nodo en la sesión

### Historial completo

Accede desde el botón **Historial** en la toolbar. Lista todas las ejecuciones del flujo, de más reciente a más antigua, con el estado, la versión ejecutada y el resultado de cada nodo paso a paso.

***

## Asistente IA (ChatPanel)

Click en **IA** en la toolbar. Desliza un panel desde la derecha donde puedes:

* **Generar un flujo completo** describiéndolo en lenguaje natural
* **Modificar nodos existentes** ("agrega un paso que envíe un email")
* **Extender el flujo** ("agrega una validación antes del envío")

El asistente carga el flujo generado directamente en el canvas, configurando cada nodo con los metadatos de sus integraciones. Usa el botón **↺** del panel para borrar el historial y empezar de nuevo.

<Tip>
  El asistente tiene contexto del flujo actual y de las integraciones disponibles. Si ya tienes nodos en el canvas, puedes pedirle que los modifique o extienda. Mientras más claro sea tu prompt, mejor el resultado.
</Tip>

***

## Bookmarks — nodos favoritos

Guarda la configuración de un nodo (código, inputs, prompt, etc.) para reutilizarla rápido.

1. Abre el panel de un nodo y haz click en **⭐ Bookmark** en el header.
2. El nodo aparece en la sidebar de Bookmarks.
3. Arrastra cualquier bookmark al canvas para crear un nodo con toda la configuración guardada.

Para quitar un bookmark, haz click en ⭐ de nuevo o en la ✕ junto al bookmark en la sidebar.

***

## Importar y exportar escenarios

| Acción       | Cómo                                                                                     |
| ------------ | ---------------------------------------------------------------------------------------- |
| **Exportar** | Toolbar inferior, click en **Exportar**, descarga un `.json` con la definición del flujo |
| **Importar** | Toolbar inferior, click en **Importar**, selecciona un `.json` exportado previamente     |

Al importar, el sistema rehidrata cada nodo con los metadatos de las integraciones disponibles. Útil para compartir flujos entre workspaces o respaldar versiones específicas.

<Warning>
  La importación **reemplaza** el canvas actual. Si tienes cambios sin guardar, guarda primero.
</Warning>

***

## Barra de herramientas inferior

| Botón          | Función                                             |
| -------------- | --------------------------------------------------- |
| **IA**         | Abre/cierra el asistente IA                         |
| **+ Paso**     | Abre el Node Picker para agregar un nodo            |
| **Alinear**    | Redistribuye los nodos en columna vertical centrada |
| **Comentario** | Agrega un nodo de comentario al canvas              |
| **Importar**   | Importa un flujo desde JSON                         |
| **Exportar**   | Exporta el flujo actual a JSON                      |
| **Activo**     | Toggle de estado activo/inactivo                    |
| **Guardar**    | Guarda/versiona el flujo                            |
| **Ejecutar**   | Ejecuta el flujo completo                           |

***

## Atajos útiles

| Atajo                  | Acción                                |
| ---------------------- | ------------------------------------- |
| `Cmd/Ctrl + S`         | Guardar                               |
| `Delete` / `Backspace` | Eliminar nodo o conexión seleccionada |

***

## Preguntas frecuentes

<AccordionGroup>
  <Accordion title="¿Por qué el botón Ejecutar no aparece activo?">
    El flujo necesita al menos un nodo Trigger conectado a un paso, y debe haber sido guardado al menos una vez (tener `scenarioId`). Verifica las conexiones y guarda antes de ejecutar.
  </Accordion>

  <Accordion title="¿Puedo probar un nodo sin ejecutar todo el flujo?">
    Sí. Abre el panel del nodo (icono de lápiz) y usa el botón **Ejecutar** dentro del panel. El resultado queda disponible como variable `{{context_key.campo}}` para los demás nodos en la sesión de testing.
  </Accordion>

  <Accordion title="¿Qué pasa si un nodo falla a mitad del flujo?">
    Depende del `on_error` del nodo. Por default (`Stop`), el flujo se detiene, los nodos siguientes quedan en `pending` y el flujo se marca como `failed`. Con `Continue`, el error se registra y el flujo avanza al siguiente nodo. Puedes ver el error exacto en el panel de Resultados.
  </Accordion>

  <Accordion title="¿Cuánto tiempo puede correr un flujo?">
    Timeout default: 5 minutos por nodo. Para flujos largos, divide el trabajo en múltiples workflows encadenados vía webhook.
  </Accordion>

  <Accordion title="¿Puedo programar reintentos automáticos?">
    Sí. En la configuración de cada nodo de Acción puedes activar reintentos con backoff exponencial (máximo 3 intentos por default).
  </Accordion>

  <Accordion title="¿Los workflows tienen rate limits?">
    Sí, varían según tu plan. Escribe a soporte para conocer los límites de tu plan específico. Los triggers de tipo cron tienen una frecuencia mínima de ejecución de 1 minuto.
  </Accordion>

  <Accordion title="¿Cómo conecto un workflow a una database?">
    **Como trigger:** usa el subtipo **Fila modificada** o **Fila agregada** sobre la database que quieras observar. **Como acción:** usa los nodos `Insertar fila`, `Actualizar fila` o `Leer filas` desde cualquier paso del flujo.
  </Accordion>

  <Accordion title="¿Cuántas versiones del flujo se guardan?">
    Todas. Cada guardado crea una versión nueva e inmutable. Solo la más reciente se ejecuta por defecto; las anteriores quedan en el historial.
  </Accordion>

  <Accordion title="¿El asistente IA puede modificar un flujo existente?">
    Sí. El asistente tiene visibilidad del canvas actual, así que puedes pedirle que agregue, modifique o elimine nodos del flujo existente.
  </Accordion>

  <Accordion title="¿Puedo cambiar el nombre de un nodo?">
    Sí. Abre el panel del nodo y edita el nombre en el header. El nuevo nombre se refleja en el canvas y se usa como base del context key en los guardados posteriores.
  </Accordion>
</AccordionGroup>
