
# Neuron Istunnon tilakone

Tämä toimintamalli on hyödyllinen, kun rakennettava kokonaisuus toimii enemmän istunnon kuin kertaluonteisen suorituksen tavoin.

Queuety-tilakoneet hallitsevat istunnon elinkaarta, Queuety-työnkulut hoitavat taustatyön, jossa tarvitaan uudelleenyrityksiä, for-each-valmistumistiloja ja tulosten kokoamista, ja Neuron hoitaa varsinaiset agenttikutsut sekä keskustelumuistin.

Tämä jako sopii hyvin tukipalveluiden copiloteille, sisäisille tutkimusavustajille, ihmistarkistusta odottaville toimituksellisille agenteille sekä keskustelusäikeille, jotka siirtyvät suunnittelun, odottamisen ja vastaamisen vaiheiden välillä.

## Elinkaaren rakenne

Tässä esimerkissä yksi tukipalveluistunto käy läpi tilat `awaiting_user`, `planning`, `waiting_on_research` ja `responding`. Tilakone tekee elinkaaren näkyväksi, kun taas taustatyönkulku kokoaa tutkimustietoa ja ilmoittaa istunnolle, kun se on valmis.

## Tilakone

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

Kun käyttäjä lähettää viestin:

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

Tilakone siirtyy tilaan `planning`, jonottaa toimintonsa ja käynnistää tutkimustyönkulun.

## Suunnittelutoiminto: käynnistä työnkulku

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

Tämä tilatoiminto ei yritä tehdä tutkimusta itse. Se käynnistää työnkulun ja tallentaa työnkulun tunnisteen koneen tilaan.

## Työnkulun vaihe: ilmoita koneelle, kun tutkimus on valmis

```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 [];
    }
}
```

Kun työnkulku päättyy, se lähettää kohteen `research_completed` takaisin koneeseen ja liittää synteesipaketin tapahtuman hyötykuormaan.

## Vastaustoiminto: kutsu kohdetta Neuron istunnon muistilla

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

Kun vastaus on luotu, tilakone siirtyy takaisin tilaan `awaiting_user` ja päivittää vastauksen julkiseen tilaan. Sama istunto voi sitten ottaa vastaan uuden tapahtuman `user_message` ja jatkaa.

## Miksi tämä on selkeämpää kuin yksi suuri työnkulku

Raskas työ vastaa edelleen työnkulkua, koska tutkimuspuoli vaatii suunnittelua, erikoistuneita suorituksia, tulosten kokoamista ja synteesiä. Pitkäikäinen tukikeskustelu taas vastaa tilakonetta, koska istunnon on seurattava, odottaako se käyttäjän vuoroa tai tutkimusta vai saako se jo lähettää vastauksen.

Tämä jako pitää suorituksen helposti luettavana ja istuntomallin selkeänä.

## Aiheeseen liittyvät dokumentit

- [Tilakoneet](https://queuety.inline0.dev/fi/docs/state-machines)
- [Agenttien orkestrointi](https://queuety.inline0.dev/fi/docs/workflows/agent-orchestration)
- [Asynkroniset siirrot](https://queuety.inline0.dev/fi/docs/workflows/async-handoffs)
- [Työnkulkujen riippuvuudet](https://queuety.inline0.dev/fi/docs/workflows/dependencies)
