# Quick Start

Comencemos con un ejemplo sencillo de dos agentes que hacen una cuenta regresiva del 10 al 1.

Primero definimos las clases de agentes y sus respectivos procedimientos para manejar mensajes. Creamos dos clases de agentes: **`Modifier`** y **`Checker`**. El agente **`Modifier`** modifica un número que se le proporciona, y el agente **`Checker`** verifica el valor según una condición. También creamos una clase de datos **`Message`**, que define los mensajes que se pasan entre los agentes.

```python
from dataclasses import dataclass
from typing import Callable

from saptiva_agents.core import DefaultTopicId, MessageContext, RoutedAgent, default_subscription, message_handler


@dataclass
class Message:
    content: int


@default_subscription
class Modifier(RoutedAgent):
    def __init__(self, modify_val: Callable[[int], int]) -> None:
        super().__init__("A modifier agent.")
        self._modify_val = modify_val

    @message_handler
    async def handle_message(self, message: Message, ctx: MessageContext) -> None:
        val = self._modify_val(message.content)
        print(f"{'-'*80}\nModifier:\nModified {message.content} to {val}")
        await self.publish_message(Message(content=val), DefaultTopicId())  # type: ignore


@default_subscription
class Checker(RoutedAgent):
    def __init__(self, run_until: Callable[[int], bool]) -> None:
        super().__init__("A checker agent.")
        self._run_until = run_until

    @message_handler
    async def handle_message(self, message: Message, ctx: MessageContext) -> None:
        if not self._run_until(message.content):
            print(f"{'-'*80}\nChecker:\n{message.content} passed the check, continue.")
            await self.publish_message(Message(content=message.content), DefaultTopicId())
        else:
            print(f"{'-'*80}\nChecker:\n{message.content} failed the check, stopping.")

```

Es posible que ya lo hayas notado: la lógica de los agentes, ya sea utilizando un modelo o un ejecutor de código, está completamente desacoplada de cómo se entregan los mensajes. Esta es la idea central: el framework proporciona una infraestructura de comunicación, y los agentes son responsables de su propia lógica. A esta infraestructura de comunicación la llamamos **Agent Runtime**.

**Agent Runtime** es un concepto clave de este framework. Además de entregar mensajes, también gestiona el ciclo de vida de los agentes. Por lo tanto, la creación de los agentes es gestionada por el runtime.

El siguiente código muestra cómo registrar y ejecutar los agentes utilizando `SingleThreadedAgentRuntime`, una implementación de runtime de agentes local y embebida.

> Nota
>
> Si estás utilizando **VSCode** u otro editor, recuerda importar `asyncio` y envolver el código con `async def main() -> None:` y ejecutar el código con la función `asyncio.run(main())`.

```python
from saptiva_agents.core import AgentId, SingleThreadedAgentRuntime

# Crear un runtime embebido local.
runtime = SingleThreadedAgentRuntime()

# Registrar los agentes modifier y checker proporcionando
# sus tipos de agente, las funciones fábrica para crear instancias y suscripciones.
await Modifier.register(
    runtime,
    "modifier",
    # Modificar el valor restando 1
    lambda: Modifier(modify_val=lambda x: x - 1),
)

await Checker.register(
    runtime,
    "checker",
    # Ejecutar hasta que el valor sea menor o igual a 1
    lambda: Checker(run_until=lambda x: x <= 1),
)

# Iniciar el runtime y enviar un mensaje directo al checker.
runtime.start()
await runtime.send_message(Message(10), AgentId("checker", "default"))
await runtime.stop_when_idle()

```

***

### Ejemplo de Interacción:

```
--------------------------------------------------------------------------------
Checker:
10 passed the check, continue.
--------------------------------------------------------------------------------
Modifier:
Modified 10 to 9
--------------------------------------------------------------------------------
Checker:
9 passed the check, continue.
--------------------------------------------------------------------------------
Modifier:
Modified 9 to 8
--------------------------------------------------------------------------------
Checker:
8 passed the check, continue.
--------------------------------------------------------------------------------
Modifier:
Modified 8 to 7
--------------------------------------------------------------------------------
Checker:
7 passed the check, continue.
--------------------------------------------------------------------------------
Modifier:
Modified 7 to 6
--------------------------------------------------------------------------------
Checker:
6 passed the check, continue.
--------------------------------------------------------------------------------
Modifier:
Modified 6 to 5
--------------------------------------------------------------------------------
Checker:
5 passed the check, continue.
--------------------------------------------------------------------------------
Modifier:
Modified 5 to 4
--------------------------------------------------------------------------------
Checker:
4 passed the check, continue.
--------------------------------------------------------------------------------
Modifier:
Modified 4 to 3
--------------------------------------------------------------------------------
Checker:
3 passed the check, continue.
--------------------------------------------------------------------------------
Modifier:
Modified 3 to 2
--------------------------------------------------------------------------------
Checker:
2 passed the check, continue.
--------------------------------------------------------------------------------
Modifier:
Modified 2 to 1
--------------------------------------------------------------------------------
Checker:
1 failed the check, stopping.
```

A partir de la salida del agente, podemos ver que el valor fue decrementado exitosamente de 10 a 1, tal como lo dictan las condiciones del modificador y del verificador.

**Saptiva-Agents** también admite un runtime de agentes distribuido, el cual puede alojar agentes que se ejecutan en diferentes procesos o máquinas, con diferentes identidades, lenguajes y dependencias.

Para aprender a usar el runtime de agentes, la comunicación, el manejo de mensajes y las suscripciones, por favor continúa leyendo las secciones siguientes a este inicio rápido.
