
# Stavové automaty

Stavové automaty a workflow řeší různé problémy.

Workflow odpovídá na otázku „jaká práce se provede dál?“. Stavový automat odpovídá na otázku „v jakém stavu se tato věc nachází a jaké události jsou odtud platné?“. Na tomto rozdílu záleží, když vytváříte něco, co není jen posloupností kroků, ale dlouhodobě existující entitou, která v čase reaguje na vnější vstupy, například relaci agenta, chatové vlákno, proces kontroly, požadavek nebo schvalovací proces.

## Rychlý příklad

```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' ]
);
```

Tento automat začíná ve stavu `awaiting_user`, po příchodu zprávy od uživatele přejde do `planning`, nechá zařazenou akci emitovat `planned` a poté čeká ve stavu `awaiting_review`, dokud externí schválení relaci nedokončí. Podstatná není samotná syntaxe kódu. Podstatné je, že životní cyklus je výslovně definovaný, lze jej kontrolovat a řídí se událostmi.

## Jak automat funguje

Při odeslání instance automatu Queuety uloží název aktuálního stavu, veřejná data stavu, verzi a hash definice, platné příchozí události pro aktuální stav a trvalou časovou osu událostí.

Pokud má vstupovaný stav `action()`, Queuety zařadí úlohu pro vstup do stavu. Tato akce může jednoduše aktualizovat veřejný stav a nechat automat čekat na další událost, nebo může emitovat `_event` a případně také `_event_payload`, aby okamžitě provedla další přechod. Pokud stav nemá akci ani koncový stav, automat pouze čeká na externí události odeslané pomocí `Queuety::machine_event()`.

## Kdy zvolit workflow a kdy stavový automat

Workflow použijte, když běh vychází především z jednotlivých kroků. Načíst data, zpracovat každou položku, počkat, syntetizovat, dokončit. Tento model se hodí, když je jasný začátek i konec a hlavní otázkou je, jaká práce se má provést dál.

Stavový automat použijte, když platné chování závisí na aktuální fázi životního cyklu. Hodí se lépe, když události mohou přicházet v různém pořadí, entita může existovat dlouhou dobu nebo potřebujete výslovně kontrolovat její životní cyklus ve stavech jako `awaiting_user`, `planning`, `running_agents`, `awaiting_review` a `completed`.

## Jak spolu oba přístupy fungují

Obě primitivní konstrukce fungují nejlépe společně, nikoli jako konkurující si řešení. Akce stavu může při přechodu vyžadujícím náročnější zpracování odeslat workflow a workflow může po dokončení práce emitovat událost zpět do automatu. V praxi tak stavový automat řídí životní cyklus, zatímco workflow provádějí náročné nebo vysoce strukturované úlohy.

## Struktura builderu

`StateMachineBuilder` zůstává záměrně malý. `initial()` a `state()` definují graf životního cyklu. `action()` připojuje zařazenou práci k jednomu stavu. `on()` určuje, které události mohou přesunout automat do dalšího stavu. `on_queue()`, `with_priority()` a `max_attempts()` řídí vykonávání akcí stavu, zatímco `version()` a `idempotency_key()` připojují trvalá metadata odeslání. `dispatch()` vytvoří instanci automatu.

Akce stavu mohou také zpřístupnit volitelnou metodu `config()`, která používá stejné klíče zásad pro zdroje jako kroky a obsluhy workflow. Díky tomu lze náročný přechod stavu zařadit do sdílené skupiny souběžnosti nebo připojit vyšší váhovou hodnotu nákladů, když akce spotřebuje větší část rozpočtu než běžný krok.

Širší model zdrojů je popsán v části [Správa zdrojů](https://queuety.inline0.dev/cs/docs/features/resource-management).

## Kontrakty

Akce při vstupu do stavu implementují `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` jsou strukturovaná data z definice akce; pokud byla akce zadána jako prostý název třídy, jsou prázdná. Queuety vytváří akce pomocí `new $class()`, takže třída akce potřebuje konstruktor bez povinných argumentů.

Akce stavu mohou také definovat volitelnou metodu `config()` s `concurrency_group`, `concurrency_limit` a `cost_units`, pokud se má zařazená akce při vstupu do stavu účastnit přijímání workerem, rozpočtů vážených front nebo poskytovatelů a dalších zásad pro zdroje.

Ochranné podmínky přechodů implementují `Queuety\Contracts\StateGuard`:

```php
namespace Queuety\Contracts;

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

## Rozhraní pro kontrolu

Ke kontrole běžících automatů použijte fasádu:

```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 );
```

Stavové automaty nemají příkazy WP-CLI: `wp queuety workflow ...` se týká pouze workflow. K jejich kontrole z příkazového řádku použijte tato rozhraní PHP, například prostřednictvím `wp eval`.

Tato rozhraní zpřístupňují název aktuálního stavu, stav životního cyklu, veřejný stav, dostupné události, metadata definice, úplnou časovou osu přechodů a normalizovaný balíček trasování pro uživatelská rozhraní debuggeru. Řádky seznamu automatů obsahují verzi definice, hash definice a idempotency key, takže seznamy mohou zobrazit zdrojovou a běhovou verzi, aniž by bylo nutné načítat každý automat zvlášť. Balíček trasování obsahuje seskupené stavy, nezpracované události, související úlohy akcí, protokoly, odkazy na artefakty, odkazy na části, vstup a výstup obsluhy, stav před a po, kontext, časové údaje a strukturované chyby.

## Relace agentů

Stavové automaty jsou obzvlášť užitečné pro systémy agentů, které se podobají spíše relacím než pipeline. Relaci, která prochází stavy `awaiting_user`, `planning`, `running_agents`, `awaiting_review` a `completed`, lze obvykle snáze pochopit jako výslovný životní cyklus než jako jedinou velmi dlouhou definici workflow s mnoha čekáními a zpětnými přechody.

## Viz také

- [Neuron Stavový automat relace](https://queuety.inline0.dev/cs/docs/examples/neuron-session-state-machine)
- [Neuron Stavový automat paměti a kontroly](https://queuety.inline0.dev/cs/docs/examples/neuron-memory-review)
- [Orchestrace agentů](https://queuety.inline0.dev/cs/docs/workflows/agent-orchestration)
- [Signály workflow](https://queuety.inline0.dev/cs/docs/workflows/signals)
- [Závislosti workflow](https://queuety.inline0.dev/cs/docs/workflows/dependencies)
- [Opakování](https://queuety.inline0.dev/cs/docs/workflows/repeats)
- [Artefakty](https://queuety.inline0.dev/cs/docs/features/artifacts)
- [PHP API](https://queuety.inline0.dev/cs/docs/api)
