
# Neuron Stroj stanj seje

Ta vzorec je uporaben, kadar se obravnavani sistem vede bolj kot seja kot pa enkratno izvajanje.

Stroji stanj Queuety upravljajo življenjski cikel seje, poteki dela Queuety pa izvajajo opravila v ozadju, pri katerih pridejo prav ponovni poskusi, načini dokončanja za vsak element in združevanje; Neuron pa skrbi za dejanske klice agenta in pomnilnik pogovora.

Ta razdelitev je primerna za pomočnike za podporo, interne raziskovalne pomočnike, uredniške agente, ki lahko počakajo na človeški pregled, ter niti klepeta, ki prehajajo med načrtovanjem, čakanjem in odgovarjanjem.

## Potek življenjskega cikla

V tem primeru seja podpore prehaja skozi `awaiting_user`, `planning`, `waiting_on_research` in `responding`. Stroj ohranja ta življenjski cikel izrecno določen, potek dela v ozadju pa zbira gradivo in sejo obvesti, ko konča.

## Stroj stanj

```php
use Queuety\Queuety;

$session_id = Queuety::machine( 'support_session' )
    ->version( 'support-session.v1' )
    ->state( 'awaiting_user' )
    ->on( 'user_message', 'planning' )
    ->state( 'planning' )
    ->action( DispatchResearchWorkflowAction::class )
    ->on( 'research_dispatched', 'waiting_on_research' )
    ->state( 'waiting_on_research' )
    ->on( 'research_completed', 'responding' )
    ->state( 'responding' )
    ->action( RespondWithNeuronAction::class )
    ->on( 'response_ready', 'awaiting_user' )
    ->dispatch( [
        'thread_id' => 'support:customer-42',
    ] );
```

Ko uporabnik pošlje sporočilo:

```php
Queuety::machine_event(
    $session_id,
    'user_message',
    [
        'session_machine_id' => $session_id,
        'message' => 'Can you compare our pricing to the main competitors?',
    ]
);
```

Stroj preide v `planning`, postavi svoje dejanje v čakalno vrsto in zažene raziskovalni potek dela.

## Dejanje načrtovanja: zaženite potek dela

```php
namespace App\StateMachines\Actions;

use Queuety\Contracts\StateAction;
use Queuety\Enums\WaitMode;
use Queuety\Queuety;

final class DispatchResearchWorkflowAction implements StateAction
{
    public function handle( array $state, ?string $event = null, array $event_payload = [], array $payload = [] ): array|string
    {
        $message = trim( (string) ( $event_payload['message'] ?? '' ) );

        $agent_workflow = Queuety::workflow( 'support_research_agent' )
            ->then( ResearchTopicStep::class );

        $research_workflow = Queuety::workflow( 'support_research_packet' )
            ->then( PlanResearchTasksStep::class )
            ->start_agents( 'agent_tasks', $agent_workflow )
            ->wait_for_agents( mode: WaitMode::All, result_key: 'agent_results' )
            ->then( SynthesizeResearchPacketStep::class )
            ->then( NotifySessionResearchReadyStep::class );

        $workflow_id = $research_workflow->dispatch( [
            'machine_id'      => $state['session_machine_id'],
            'thread_id'       => $state['thread_id'],
            'customer_prompt' => $message,
        ] );

        return [
            'latest_user_message'  => $message,
            'research_workflow_id' => $workflow_id,
            '_event'               => 'research_dispatched',
        ];
    }
}
```

To dejanje stanja ne poskuša izvesti raziskave samo. Zažene potek dela in shrani njegov ID v stanje stroja.

## Korak poteka dela: obvestite stroj, ko je raziskava pripravljena

```php
namespace App\Workflow\Steps;

use Queuety\Queuety;
use Queuety\Step;

final class NotifySessionResearchReadyStep implements Step
{
    public function handle( array $state ): array
    {
        Queuety::machine_event(
            $state['machine_id'],
            'research_completed',
            [
                'research_packet' => $state['research_packet'],
            ]
        );

        return [];
    }

    public function config(): array
    {
        return [];
    }
}
```

Ko se potek dela konča, pošlje `research_completed` nazaj v stroj in kot podatke dogodka vključi sintetizirani paket gradiva.

## Dejanje odgovarjanja: pokličite Neuron s pomnilnikom seje

```php
namespace App\StateMachines\Actions;

use App\Neuron\SupportAgent;
use NeuronAI\Chat\Messages\UserMessage;
use Queuety\Contracts\StateAction;

final class RespondWithNeuronAction implements StateAction
{
    public function handle( array $state, ?string $event = null, array $event_payload = [], array $payload = [] ): array|string
    {
        // Queuety creates actions with `new RespondWithNeuronAction()`, so build dependencies here.
        $pdo = new \PDO( $_ENV['NEURON_DB_DSN'], $_ENV['NEURON_DB_USER'], $_ENV['NEURON_DB_PASSWORD'] );

        $agent = new SupportAgent(
            threadId: $state['thread_id'],
            pdo: $pdo,
        );

        $message = $agent->chat(
            new UserMessage(
                sprintf(
                    "Answer the user message '%s' using this research packet:\n\n%s",
                    $state['latest_user_message'],
                    json_encode( $state['research_packet'] ?? [], JSON_PRETTY_PRINT )
                )
            )
        )->getMessage();

        return [
            'assistant_reply' => $message->getContent(),
            '_event'          => 'response_ready',
        ];
    }
}
```

Ko je odgovor ustvarjen, stroj preide nazaj v `awaiting_user` s posodobljenim odgovorom v javnem stanju. Seja lahko nato sprejme nov dogodek `user_message` in nadaljuje.

## Zakaj je to preglednejše kot en velik potek dela

Zahtevnejše delo še vedno poteka v obliki poteka dela, saj raziskovalni del potrebuje načrtovanje, izvajanja specializiranih agentov, združevanje in sintezo. Dolgotrajen pogovor s podporo pa je primernejši za stroj stanj, saj mora seja spremljati, ali čaka na uporabnika, na raziskavo ali pa že lahko pošlje odgovor.

Ta razdelitev ohranja preglednost izvajalnega okolja in izrecno določa model seje.

## Povezana dokumentacija

- [Stroji stanj](https://queuety.inline0.dev/sl/docs/state-machines)
- [Orkestracija agentov](https://queuety.inline0.dev/sl/docs/workflows/agent-orchestration)
- [Asinhroni predaji](https://queuety.inline0.dev/sl/docs/workflows/async-handoffs)
- [Odvisnosti potekov dela](https://queuety.inline0.dev/sl/docs/workflows/dependencies)
