
# Máquinas de Estado

Máquinas de estado e workflows resolvem problemas diferentes.

Um workflow responde: “qual trabalho será executado em seguida?” Uma máquina de estado responde: “em que estado está esta entidade e quais eventos são válidos a partir daqui?” Essa diferença importa quando o que você está criando não é apenas uma sequência de etapas, mas uma entidade duradoura que reage a entradas externas ao longo do tempo, como uma sessão de agente, um tópico de conversa, um ciclo de revisão, um chamado ou um fluxo de aprovação.

## Exemplo rápido

```php
use Queuety\Enums\StateMachineStatus;
use Queuety\Queuety;

$machine_id = Queuety::machine( 'agent_session' )
    ->version( 'agent-session.v1' )
    ->state( 'awaiting_user' )
    ->on( 'user_message', 'planning' )
    ->state( 'planning' )
    ->action( PlanSessionAction::class )
    ->on( 'planned', 'awaiting_review' )
    ->state( 'awaiting_review' )
    ->on( 'approve', 'completed', ReviewApprovedGuard::class )
    ->on( 'reject', 'awaiting_user' )
    ->state( 'completed', StateMachineStatus::Completed )
    ->dispatch( [ 'thread_id' => 42 ] );

Queuety::machine_event(
    $machine_id,
    'user_message',
    [ 'message' => 'Find competitors for this product' ]
);

Queuety::machine_event(
    $machine_id,
    'approve',
    [ 'approved' => true, 'reviewer' => 'editor@example.com' ]
);
```

Esta máquina começa em `awaiting_user`, passa para `planning` quando chega uma mensagem do usuário, permite que a ação enfileirada emita `planned` e, em seguida, aguarda em `awaiting_review` até que uma aprovação externa conclua a sessão. O ponto importante não é apenas a sintaxe do código. É que o ciclo de vida é explícito, inspecionável e orientado a eventos.

## Como uma máquina funciona

Quando uma instância de máquina é despachada, Queuety persiste o nome do estado atual, o payload público do estado, a versão e o hash da definição, os eventos de entrada válidos para o estado atual e uma linha do tempo duradoura de eventos.

Se o estado acessado tiver um `action()`, Queuety enfileira um job de entrada no estado. Essa ação pode simplesmente atualizar o estado público e deixar a máquina aguardando o próximo evento, ou pode emitir `_event` e, opcionalmente, `_event_payload` para realizar imediatamente a próxima transição. Se o estado não tiver ação nem status terminal, a máquina simplesmente aguarda eventos externos enviados com `Queuety::machine_event()`.

## Como escolher entre workflows e máquinas de estado

Use um workflow quando a execução for fundamentalmente orientada a etapas. Buscar dados, aguardar por cada item de trabalho, sintetizar e concluir. Esse modelo é adequado quando há um início e um fim claros e a principal questão é qual trabalho deve ser executado em seguida.

Use uma máquina de estado quando o comportamento válido depender da fase atual do ciclo de vida. Ela é mais adequada quando os eventos podem chegar em ordens diferentes, quando a entidade pode existir por muito tempo ou quando você precisa inspecionar explicitamente o ciclo de vida com estados como `awaiting_user`, `planning`, `running_agents`, `awaiting_review` e `completed`.

## Como os dois se complementam

As duas primitivas funcionam melhor juntas do que competindo entre si. Uma ação de estado pode despachar um workflow quando uma transição exige uma execução mais pesada, e um workflow pode emitir um evento de volta para uma máquina quando esse trabalho termina. Na prática, isso permite que a máquina de estado controle o ciclo de vida, enquanto os workflows executam o trabalho custoso ou altamente estruturado.

## Estrutura do builder

`StateMachineBuilder` permanece intencionalmente pequeno. `initial()` e `state()` definem o grafo do ciclo de vida. `action()` associa trabalho enfileirado a um estado. `on()` declara quais eventos podem mover a máquina para o próximo estado. `on_queue()`, `with_priority()` e `max_attempts()` controlam como as ações de estado são executadas, enquanto `version()` e `idempotency_key()` associam metadados duradouros de despacho. `dispatch()` cria a instância da máquina.

As ações de estado também podem expor um método opcional `config()`, usando as mesmas chaves de política de recursos usadas pelas etapas e handlers de workflow. Isso permite manter uma transição de estado custosa dentro de um grupo de concorrência compartilhado ou atribuir um peso de custo maior quando uma ação consome mais recursos do que uma etapa normal.

O modelo mais amplo de recursos está descrito em [Gerenciamento de recursos](https://queuety.inline0.dev/pt/docs/features/resource-management).

## Contratos

As ações de entrada no estado implementam `Queuety\Contracts\StateAction`:

```php
namespace Queuety\Contracts;

interface StateAction {
    public function handle( array $state, ?string $event = null, array $event_payload = [], array $payload = [] ): array|string;
}
```

`$payload` é o payload estruturado da definição da ação; fica vazio quando a ação é fornecida como um nome simples de classe. Queuety cria ações com `new $class()`, portanto uma classe de ação precisa ter um construtor sem argumentos obrigatórios.

As ações de estado também podem definir um método opcional `config()` com `concurrency_group`, `concurrency_limit` e `cost_units` quando a ação de entrada enfileirada deve participar da admissão de workers, dos limites de fila ponderada ou de provedores, e de outras políticas de recursos.

As condições de transição implementam `Queuety\Contracts\StateGuard`:

```php
namespace Queuety\Contracts;

interface StateGuard {
    public function allows( array $state, array $event_payload, string $event, array $payload = [] ): bool;
}
```

## APIs de inspeção

Use a fachada para inspecionar máquinas em execução:

```php
$status   = Queuety::machine_status( $machine_id );
$machines = Queuety::list_machines();
$events   = Queuety::machine_timeline( $machine_id );
$trace    = Queuety::machine_trace( $machine_id );
$state    = Queuety::machine_state_at( $machine_id, $event_id );
```

Máquinas de estado não têm comandos WP-CLI: `wp queuety workflow ...` abrange apenas workflows. Use estas APIs PHP, por exemplo por meio de `wp eval`, para inspecionar máquinas pela linha de comando.

Essas APIs expõem o nome do estado atual, o status do ciclo de vida, o estado público, os eventos disponíveis, os metadados da definição, a linha do tempo completa das transições e um pacote de rastreamento normalizado para interfaces de depuração. As linhas da lista de máquinas incluem a versão da definição, o hash da definição e a chave de idempotência, para que as telas de lista possam mostrar a versão de origem e de execução sem carregar cada máquina individualmente. O pacote de rastreamento inclui estados agrupados, eventos brutos, jobs de ação correlacionados, logs, referências a artefatos, referências a blocos, entrada e saída do handler, estado antes e depois, contexto, tempos e erros estruturados.

## Sessões de agentes

Máquinas de estado são especialmente úteis para sistemas de agentes que se comportam mais como sessões do que como pipelines. Uma sessão que passa por `awaiting_user`, `planning`, `running_agents`, `awaiting_review` e `completed` costuma ser mais fácil de compreender como um ciclo de vida explícito do que como uma definição de workflow muito longa, com muitas esperas e retornos a etapas anteriores.

## Veja também

- [Neuron Máquina de estado de sessão](https://queuety.inline0.dev/pt/docs/examples/neuron-session-state-machine)
- [Neuron Máquina de estado de memória e revisão](https://queuety.inline0.dev/pt/docs/examples/neuron-memory-review)
- [Orquestração de agentes](https://queuety.inline0.dev/pt/docs/workflows/agent-orchestration)
- [Sinais de workflow](https://queuety.inline0.dev/pt/docs/workflows/signals)
- [Dependências de workflow](https://queuety.inline0.dev/pt/docs/workflows/dependencies)
- [Repetições](https://queuety.inline0.dev/pt/docs/workflows/repeats)
- [Artefatos](https://queuety.inline0.dev/pt/docs/features/artifacts)
- [PHP API](https://queuety.inline0.dev/pt/docs/api)
