Neuron Memory + Review State Machine
This pattern is useful when an agent should keep conversational context across repeated human review rounds, but the overall lifecycle should still be orchestrated by Queuety.
Queuety owns the review state machine, while Neuron owns the agent memory for the drafting thread.
Why Neuron memory helps here
If a reviewer rejects a draft and asks for revisions, the next agent call should not have to reconstruct the whole context from scratch.
Neuron's SQLChatHistory is a good fit for that because the agent can keep working inside the same conversation thread while Queuety routes reviewer decisions and revision rounds.
The Neuron agent with SQL-backed history
namespace App\Neuron;
use NeuronAI\Agent\Agent;
use NeuronAI\Chat\History\ChatHistoryInterface;
use NeuronAI\Chat\History\SQLChatHistory;
use NeuronAI\Providers\AIProviderInterface;
use NeuronAI\Providers\Anthropic\Anthropic;
use NeuronAI\SystemPrompt;
final class EditorAgent extends Agent
{
public function __construct(
private readonly string $threadId,
private readonly \PDO $pdo,
) {}
protected function provider(): AIProviderInterface
{
return new Anthropic(
key: $_ENV['ANTHROPIC_API_KEY'],
model: $_ENV['ANTHROPIC_MODEL'],
);
}
protected function chatHistory(): ChatHistoryInterface
{
return new SQLChatHistory(
thread_id: $this->threadId,
pdo: $this->pdo,
table: 'neuron_chat_history',
contextWindow: 50000,
);
}
public function instructions(): string
{
return (string) new SystemPrompt(
background: [
'You are an editorial agent for long-form product briefs.',
'Apply reviewer notes without losing the original intent.',
],
);
}
}Draft once, revise with the same memory thread
namespace App\StateMachines\Actions;
use App\Neuron\EditorAgent;
use NeuronAI\Chat\Messages\UserMessage;
use Queuety\Contracts\StateAction;
final class DraftBriefAction implements StateAction
{
public function __construct(private readonly \PDO $pdo) {}
public function handle(array $state, ?string $event = null, array $event_payload = []): array|string
{
$threadId = $state['neuron_thread_id'] ?? sprintf(
'brief:%d:editor',
$state['brief_id'],
);
$prompt = "Write the first draft for brief {$state['brief_id']}.";
if ('reject' === $event) {
$prompt = sprintf(
'Revise the draft using these review notes: %s',
$event_payload['reason'] ?? 'Tighten the draft and address reviewer concerns.',
);
}
$agent = new EditorAgent($threadId, $this->pdo);
$message = $agent->chat(
new UserMessage($prompt)
)->getMessage();
return [
'neuron_thread_id' => $threadId,
'draft_markdown' => $message->getContent(),
'review_round' => (int) ($state['review_round'] ?? 0) + 1,
'_event' => 'draft_ready',
];
}
}The Queuety state machine
use Queuety\Enums\StateMachineStatus;
use Queuety\Queuety;
$machine_id = Queuety::machine('brief_review_session')
->version('brief-review-session.v1')
->state('drafting')
->action(DraftBriefAction::class)
->on('draft_ready', 'awaiting_review')
->state('awaiting_review')
->on('approve', 'completed')
->on('reject', 'drafting')
->state('completed', StateMachineStatus::Completed)
->dispatch([
'brief_id' => 42,
]);
Queuety::machine_event(
$machine_id,
'reject',
[ 'reason' => 'Tighten the introduction and add pricing context.' ]
);
Queuety::machine_event(
$machine_id,
'approve',
[ 'reviewer' => 'editor@example.com' ]
);The first pass enters drafting, runs the queued action, and transitions into awaiting_review.
If the reviewer rejects the draft, the machine moves back into drafting. Because the reject event payload is passed into DraftBriefAction, the next draft can use the reviewer notes without losing the original Neuron thread history.
Why this is cleaner than a workflow repeat
This problem is lifecycle-oriented. A draft waits for human review, a reviewer can approve or reject it, rejection returns the session to drafting, and approval finishes the session. That maps more directly to a state machine than to a linear workflow with a back-edge.
Workflow state is still excellent for orchestration facts such as review round count, artifact IDs, workflow IDs, and routing decisions. Neuron memory is better for conversational context like prior prompts, iterative revisions, and model responses that should remain part of the drafting thread.
Using both gives each system the job it is best at.
When to keep this as a workflow instead
Prefer a workflow when the review path is tightly bounded and execution-oriented, for example:
Generate one draft, wait for one approval, and publish.
Prefer a state machine when the session may revisit the same states several times and outside events drive the lifecycle.